提示
事務(wù)傳播行為率先出現(xiàn)在 Spring 框架中,HasorDB 對(duì)其思想并未有什么改進(jìn)而是在 HasorDB 中提供了一套完整的實(shí)現(xiàn)。
簡(jiǎn)單的理解就是多個(gè)事務(wù)方法相互調(diào)用時(shí),事務(wù)如何在這些方法間傳播。舉個(gè)例子:
?方法A
? 是一個(gè)事務(wù)的方法,在執(zhí)行過(guò)程中調(diào)用了 ?方法B
?。 接下來(lái) ?方法B
? 有無(wú)事務(wù)以及 ?方法B
? 對(duì)事務(wù)的要求不同都會(huì)對(duì) ?方法A
?的事務(wù)具體執(zhí)行造成影響。 同時(shí) ?方法A
? 的事務(wù)對(duì)? 方法B
? 的事務(wù)執(zhí)行也有影響,這種影響具體是什么就由兩個(gè)方法所定義的事務(wù)傳播行為所決定。
Propagation.REQUIRED
?嘗試加入已經(jīng)存在的事務(wù)中,如果沒(méi)有則開啟一個(gè)新的事務(wù)。
時(shí)間 | 事務(wù)1 | 事務(wù)2(REQUIRED) | 效果 |
---|---|---|---|
T1 | begin | ||
T2 | insert data1 | ||
T3 | begin | 什么都不做 | |
T4 | insert data2 | ||
T5 | commit/rollback | 什么都不做 | |
T5 | insert data3 | ||
T5 | commit/rollback |
Propagation.REQUIRES_NEW
?將掛起當(dāng)前存在的事務(wù)掛起(如果存在的話)并且開啟一個(gè)全新的事務(wù),新事務(wù)與已存在的事務(wù)之間彼此沒(méi)有關(guān)系。
DataSourceManager
? 中正在使用的同步資源被臨時(shí)保存
DataSourceManager
?會(huì)得到一個(gè)全新的數(shù)據(jù)庫(kù)連接。
時(shí)間 | 事務(wù)1 | 事務(wù)2(REQUIRES_NEW) | 效果 |
---|---|---|---|
T1 | begin | ||
T2 | insert data1 | ||
T3 | begin | 產(chǎn)生新的連接并且和當(dāng)前線程綁定,以滿足 本地同步 | |
T4 | insert data2 | 在新連接上寫入 | |
T5 | commit/rollback | 操作新的 Connection
|
|
T5 | insert data3 | ||
T5 | commit/rollback |
Propagation.NESTED
?在當(dāng)前事務(wù)中通過(guò) ?Savepoint
? 方式開啟一個(gè)子事務(wù)。
時(shí)間 | 事務(wù)1 | 事務(wù)2(NESTED) | 效果 |
---|---|---|---|
T1 | begin | ||
T2 | insert data1 | ||
T3 | begin | 創(chuàng)建事務(wù)保存點(diǎn) | |
T4 | insert data2 | ||
T5 | commit/rollback | commit 會(huì)釋放保存點(diǎn)、rollback 會(huì)回退到 T3 | |
T5 | insert data3 | ||
T5 | commit/rollback |
Propagation.SUPPORTS
?如果當(dāng)前沒(méi)有事務(wù)存在,就以非事務(wù)方式執(zhí)行;如果有,就使用當(dāng)前事務(wù)。以下面的執(zhí)行為例:
SUPPORTS
?行為是事務(wù)傳播屬性中最簡(jiǎn)單的一種行為,其行為本質(zhì)上強(qiáng)調(diào)了 不作為
時(shí)間 | 事務(wù)1 | 事務(wù)2(SUPPORTS) | 效果 |
---|---|---|---|
T1 | begin | ||
T2 | insert data1 | ||
T3 | begin | ||
T4 | insert data2 | 注1 若 T1 開啟了事務(wù),那么效果等同于 REQUIRED
|
|
T5 | commit/rollback | 什么都不做 | |
T5 | insert data3 | ||
T5 | commit/rollback |
Connection
?對(duì)象的 ?autoCommit
?屬性為 ?false
?。
能夠?qū)е聠?dòng)事務(wù)的傳播行為有 ?REQUIRED
?、?REQUIRES_NEW
?和 ?NESTED
?,如果使用 低級(jí)別 API 手動(dòng)改變 autoCommit 狀態(tài)也會(huì)導(dǎo)致進(jìn)入事務(wù)狀態(tài)。Propagation.NOT_SUPPORTED
?如果當(dāng)前沒(méi)有事務(wù)存在,就以非事務(wù)方式執(zhí)行;如果有,就將當(dāng)前事務(wù)掛起。以下面的執(zhí)行為例:
注意
將掛起當(dāng)前存在的事務(wù)掛起(如果存在的話)并且開啟一個(gè)全新的事務(wù),新事務(wù)與已存在的事務(wù)之間彼此沒(méi)有關(guān)系。
- 掛起會(huì)導(dǎo)致 ?
DataSourceManager
?中正在使用的同步資源被臨時(shí)保存。
- 在掛起之后訪問(wèn) ?
DataSourceManager
?會(huì)得到一個(gè)全新的數(shù)據(jù)庫(kù)連接。
時(shí)間 | 事務(wù)1 | 事務(wù)2(NOT_SUPPORTED) | 效果 |
---|---|---|---|
T1 | begin | ||
T2 | insert data1 | ||
T3 | begin | 注1 若 T1 開啟了事務(wù),那么會(huì)掛起當(dāng)前事務(wù)。但不開啟新的事務(wù) | |
T4 | insert data2 | ||
T5 | commit/rollback | 注2 若 T3 掛起了事務(wù),那么會(huì)恢復(fù)它。 | |
T5 | insert data3 | ||
T5 | commit/rollback |
Connection
?對(duì)象的 ?autoCommit
?屬性為 ?false
?。 能夠?qū)е聠?dòng)事務(wù)的傳播行為有 ?REQUIRED
?、?REQUIRES_NEW
?和 ?NESTED
?,如果使用 低級(jí)別 API 手動(dòng)改變 ?autoCommit
?狀態(tài)也會(huì)導(dǎo)致進(jìn)入事務(wù)狀態(tài)。DataSourceManager
?的當(dāng)前綁定連接為之前的那一個(gè)。Propagation.NEVER
?如果當(dāng)前沒(méi)有事務(wù)存在,就以非事務(wù)方式執(zhí)行;如果有就拋出異常。
時(shí)間 | 事務(wù)1 | 事務(wù)2(NEVER) | 效果 |
---|---|---|---|
T1 | begin | ||
T2 | insert data1 | ||
T3 | begin | 注1 若 T1 開啟了事務(wù),那么會(huì)拋出異常 | |
T4 | insert data2 | ||
T5 | commit/rollback | 什么都不做 | |
T5 | insert data3 | ||
T5 | commit/rollback |
NOT_SUPPORTED
? 那么 T3 環(huán)節(jié)上 ?NEVER
?行為就不會(huì)報(bào)錯(cuò)。它的行為會(huì)和 ?SUPPORTS
?等價(jià)。 若 T1 這個(gè)動(dòng)作導(dǎo)致了 ?Connection
?對(duì)象的 ?autoCommit
?屬性為 ?false
?那么 T3 環(huán)節(jié)就會(huì)報(bào)錯(cuò)。autoCommit
?為 ?false
?傳播行為有 ?REQUIRED
?、?REQUIRES_NEW
?和 ?NESTED
?,也可以通過(guò)使用 低級(jí)別 API 改變。Propagation.MANDATORY
?如果當(dāng)前沒(méi)有事務(wù)存在,就拋出異常;如果有,就使用當(dāng)前事務(wù)。
時(shí)間 | 事務(wù)1 | 事務(wù)2(NEVER) | 效果 |
---|---|---|---|
T1 | begin | ||
T2 | insert data1 | ||
T3 | begin | 注1 若 T1 不存在事務(wù),那么會(huì)拋出異常 | |
T4 | insert data2 | ||
T5 | commit/rollback | 什么都不做 | |
T5 | insert data3 | ||
T5 | commit/rollback |
MANDATORY
?是要求必須 T1 環(huán)節(jié)產(chǎn)生了一個(gè)事務(wù),否則會(huì)報(bào)錯(cuò)。 因此若 T1 環(huán)節(jié)使用的是? NOT_SUPPORTED
?行為,那么 T3 環(huán)節(jié)就會(huì)報(bào)錯(cuò)。
更多建議: