一衰齐、簡單說明
傳播屬性 | 描述 |
---|---|
PROPAGATION_REQUIRED | 如果當(dāng)前沒有事務(wù)杏头,就創(chuàng)建一個事務(wù),如果當(dāng)前存在事務(wù)楚里,就加入該事務(wù)。 |
PROPAGATION_REQUIRED_NEW | 當(dāng)前的方法必須啟動新事務(wù)猎贴,并在它自己的事務(wù)內(nèi)運行班缎,不管是否存著事務(wù),都開啟新事務(wù)她渴。 |
PROPAGATION_SUPPORTS | 如果當(dāng)前存在事務(wù)达址,就加入該事務(wù),如果當(dāng)前不存在事務(wù)趁耗,就以非事務(wù)的方式執(zhí)行苏携。 |
PROPAGATION_NOT_SUPPORTED | 當(dāng)前的方法不應(yīng)該運行在事務(wù)中,如果有運行的事務(wù)对粪,將它掛起 |
PROPAGATION_MANDATORY | 如果當(dāng)前存在事務(wù)右冻,就加入當(dāng)前事務(wù)装蓬,如果當(dāng)前不存在事務(wù),就拋出異常 |
PROPAGATION_NEVER | 當(dāng)前的方法不應(yīng)該運行在事務(wù)中纱扭,如果當(dāng)前存在事務(wù)牍帚,就拋出異常 |
PROPAGATION_NESTED | 如果有事務(wù)在運行,當(dāng)前的方法就應(yīng)該在這個事務(wù)的嵌套事務(wù)內(nèi)運行乳蛾,否則暗赶,就啟動一個新的事務(wù)肃叶,并在它自己的事務(wù)內(nèi)運行蹂随。 |
二、具體案例描述
1.PROPAGATION_REQUIRED
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodA(){
doPreSomething;
methodB();
doSufSomething;
}
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodB(){
doSomething;
}
在兩個方法的事務(wù)傳播級別都是PROPAGATION_REQURIED的時候因惭。
如果調(diào)用方法A岳锁,會開啟一個事務(wù),在方法A內(nèi)部調(diào)用方法B蹦魔,由于方法A已經(jīng)存在開啟尚未提交的事務(wù)激率,方法B不會就不會再開啟一個新的事務(wù),方法B會直接加入方法A的事務(wù)中執(zhí)行勿决,這樣如果在執(zhí)行方法B的時候出了異常導(dǎo)致事務(wù)回滾乒躺,則B的方法和A的方法都會回滾。如果A的doPreSomething()和方法B都執(zhí)行成功了低缩,但是在執(zhí)行doSufSomething()方法的時候拋出了異常導(dǎo)致事務(wù)回滾嘉冒,則doSufSomething()、methodB()和doPreSomething()都會回滾咆繁。
如果不通過方法A而單獨調(diào)用方法B讳推,則會開啟一個事務(wù)。
PROPAGATION_REQURIED所有方法公用一個事務(wù)么介,要么一起成功提交娜遵,要么一起失敗回滾。
如果嵌套執(zhí)行的方法要求一起執(zhí)行成功或者一起回滾壤短,則選擇該事物傳播級別设拟。
執(zhí)行邏輯:
開啟事務(wù)
執(zhí)行方法A的doPreSomething
執(zhí)行方法B
執(zhí)行方法A的doSufSomething
提交或回滾事務(wù)
2.PROPAGATION_REQUIRED_NEW
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodA(){
doPreSomething;
methodB();
dosufSomething;
}
@Transactional(propagation=PROPAGATION_REQUIRED_NEW)
pubilc void methodB(){
doSomething;
}
在事務(wù)的隔離級別是PROPAGATION_REQUIRED_NEW的時候。
如果調(diào)用方法A久脯,會開啟一個事務(wù)纳胧,在方法內(nèi)部調(diào)用方法B,方法B會自己再開啟一個事務(wù)帘撰,然后方法B在自己的事務(wù)內(nèi)部執(zhí)行跑慕,如果方法B執(zhí)行失敗拋出異常,那么事務(wù)B會進行回滾,事務(wù)A不會受到影響可以繼續(xù)執(zhí)行核行,如果在方法B執(zhí)行成功牢硅,方法B的事務(wù)會單獨進行提交;B提交事務(wù)之后接著執(zhí)行A的doSufSomething()方法芝雪,如果執(zhí)行成功提交A的事務(wù)减余,如果拋出異常,則只回滾A的事務(wù)惩系,對B的事務(wù)不會進行影響位岔,也就說B的事務(wù)不會進行回滾。
如果不通過方法A而單獨調(diào)用方法B堡牡,則會開啟一個事務(wù)抒抬。
PROPAGATION_REQURIED_NEW所有方法使用各自的事務(wù),各自提交或者回滾各自的事務(wù)晤柄,相互之間不會造成影響擦剑。
如果嵌套執(zhí)行的方法要求各自事務(wù)獨立,不能進行相互影響可免,則選擇本事務(wù)傳播級別抓于。
執(zhí)行邏輯
開啟事務(wù)
執(zhí)行方法A的doPreSomething
開啟另一個事務(wù)2
執(zhí)行方法B
提交或者回滾事務(wù)2
執(zhí)行方法A的doSufSomething
提交或回滾事務(wù)
3.PROPAGATION_SUPPORTS
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodA(){
doPreSomething;
methodB();
doSufSomething;
}
@Transactional(propagation=PROPAGATION_SUPPORTS)
pubilc void methodB(){
doSomething;
}
在事務(wù)的隔離級別是PROPAGATION_SUPPORTS的時候做粤。
如果調(diào)用方法A浇借,會開啟一個事務(wù),在方法A內(nèi)部調(diào)用方法B怕品,由于方法A已經(jīng)存在開啟尚未提交的事務(wù)妇垢,方法B會直接加入方法A的事務(wù)中執(zhí)行,這樣如果在執(zhí)行方法B的時候出了異常導(dǎo)致事務(wù)回滾肉康,則B的方法和A的方法都會回滾闯估。如果A的doPreSomething()和方法B都執(zhí)行成功了,但是在執(zhí)行doSufSomething()方法的時候拋出了異常導(dǎo)致事務(wù)回滾吼和,則doSufSomething()涨薪、methodB()和doPreSomething()都會回滾。
如果不通過方法A而單獨調(diào)用方法B炫乓,則方法B不會開啟事務(wù)刚夺,直接會以非事務(wù)的方式執(zhí)行。
PROPAGATION_SUPPORTS如果存著事務(wù)就加入和PROPAGATION_REQUIRED傳播級別一致末捣,如果當(dāng)前不存在事務(wù)侠姑,則不會創(chuàng)建新的事務(wù),以非事務(wù)的方式執(zhí)行箩做。
如果嵌套執(zhí)行的方法要求一起執(zhí)行成功或者一起回滾莽红,單獨執(zhí)行時候以非事務(wù)方式執(zhí)行,則選擇該事物傳播級別邦邦。
執(zhí)行邏輯:
開啟事務(wù)
執(zhí)行方法A的doPreSomething
執(zhí)行方法B
執(zhí)行方法A的doSufSomething
提交或回滾事務(wù)
4.PROPAGATION_NOT_SUPPORTED
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodA(){
doPreSomething;
methodB();
doSufSomething;
}
@Transactional(propagation=PROPAGATION_NOT_SUPPORTED)
pubilc void methodB(){
doSomething;
}
在事務(wù)的隔離級別是PROPAGATION_NOT_SUPPORTED的時候安吁。
如果調(diào)用方法A醉蚁,會開啟一個事務(wù),在方法A內(nèi)部調(diào)用方法B鬼店,由于方法A已經(jīng)存在開啟尚未提交的事務(wù)馍管,方法B不允許在事務(wù)內(nèi)部執(zhí)行,這時候事務(wù)就會掛起薪韩,在非事務(wù)的狀態(tài)中執(zhí)行方法B确沸,不管方法B是執(zhí)行成功還是執(zhí)行失敗,都不會對當(dāng)前事務(wù)造成影響俘陷。如果A的doPreSomething()和方法B都執(zhí)行成功了罗捎,但是在執(zhí)行doSufSomething()方法的時候拋出了異常導(dǎo)致事務(wù)回滾,則doSufSomething()和doPreSomething()會回滾拉盾,而方法B不會受到任何影響桨菜,因為它是在非事務(wù)中執(zhí)行的。
如果不通過方法A而單獨調(diào)用方法B捉偏,則方法B不會開啟事務(wù)倒得,直接會以非事務(wù)的方式執(zhí)行。
PROPAGATION_NOT_SUPPORTED如果存著事務(wù)就掛起當(dāng)前事務(wù)夭禽,以非事務(wù)的方式運行自己霞掺,如果當(dāng)前不存在事務(wù),則不會創(chuàng)建新的事務(wù)讹躯,以非事務(wù)的方式執(zhí)行菩彬。
如果嵌套執(zhí)行的方法要求內(nèi)部嵌套方法不會對外部方法事務(wù)造成影響并且內(nèi)部方法不需要事務(wù),單獨執(zhí)行時候以非事務(wù)方式執(zhí)行潮梯,則選擇該事物傳播級別骗灶。
執(zhí)行邏輯:
開啟事務(wù)
執(zhí)行方法A的doPreSomething
掛起事務(wù)
執(zhí)行方法B
重新啟用掛起的事務(wù)
執(zhí)行方法A的doSufSomething
提交或回滾事務(wù)
5.PROPAGATION_MANDATORY
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodA(){
doPreSomething;
methodB();
doSufSomething;
}
@Transactional(propagation=PROPAGATION_MANDATORY)
pubilc void methodB(){
doSomething;
}
在事務(wù)的隔離級別是PROPAGATION_MANDATORY的時候。
如果調(diào)用方法A秉馏,會開啟一個事務(wù)耙旦,在方法A內(nèi)部調(diào)用方法B,由于方法A已經(jīng)存在開啟尚未提交的事務(wù)萝究,方法B會直接加入方法A的事務(wù)中執(zhí)行免都,這樣如果在執(zhí)行方法B的時候出了異常導(dǎo)致事務(wù)回滾,則B的方法和A的方法都會回滾糊肤。如果A的doPreSomething()和方法B都執(zhí)行成功了琴昆,但是在執(zhí)行doSufSomething()方法的時候拋出了異常導(dǎo)致事務(wù)回滾,則doSufSomething()馆揉、methodB()和doPreSomething()都會回滾业舍。
如果不通過方法A而單獨調(diào)用方法B,則方法B會直接報錯,因為方法B的事務(wù)傳播級別是PROPAGATION_MANDATORY,而其不允許在沒有事務(wù)的環(huán)境下執(zhí)行舷暮。
PROPAGATION_SUPPORTS如果存著事務(wù)就加入和PROPAGATION_REQUIRED傳播級別一致态罪,如果當(dāng)前不存在事務(wù),會直接進行報錯下面,不允許以非事務(wù)的方式執(zhí)行复颈。
如果嵌套執(zhí)行的方法要求一起執(zhí)行成功或者一起回滾,單獨執(zhí)行時候不允許以非事務(wù)方式執(zhí)行沥割,則選擇該事物傳播級別耗啦。
執(zhí)行邏輯:
開啟事務(wù)
執(zhí)行方法A的doPreSomething
執(zhí)行方法B
執(zhí)行方法A的doSufSomething
提交或回滾事務(wù)
6.PROPAGATION_NEVER
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodA(){
doPreSomething;
methodB();
doSufSomething;
}
@Transactional(propagation=PROPAGATION_NEVER)
pubilc void methodB(){
doSomething;
}
在事務(wù)的隔離級別是PROPAGATION_NERVR的時候。
如果調(diào)用方法A机杜,會開啟一個事務(wù)帜讲,在方法A內(nèi)部調(diào)用方法B,由于方法A已經(jīng)存在開啟尚未提交的事務(wù)椒拗,方法B的傳播級別為PROPAGATION_NEVER似将,其不允許在事務(wù)內(nèi)部執(zhí)行,所以這時候就會直接報錯蚀苛。
如果不通過方法A而單獨調(diào)用方法B在验,則方法B會直接在沒有事務(wù)的環(huán)境中執(zhí)行。
PROPAGATION_NERVER如果存著事務(wù)就直接報錯堵未,如果當(dāng)前不存在事務(wù)腋舌,會以非事務(wù)的方式執(zhí)行。
如果嵌套執(zhí)行的方法要求內(nèi)部方法不允許在事務(wù)中執(zhí)行兴溜,單獨執(zhí)行時候必須以非事務(wù)方式執(zhí)行侦厚,則選擇該事物傳播級別耻陕。
執(zhí)行邏輯:
開啟事務(wù)
執(zhí)行方法A的doPreSomething
執(zhí)行方法B拙徽,直接報錯
回滾事務(wù)
7.PROPAGATION_NESTED
@Transactional(propagation=PROPAGATION_REQUIRED)
pubilc void methodA(){
doPreSomething;
methodB();
doSufSomething;
}
@Transactional(propagation=PROPAGATION_NESTED)
pubilc void methodB(){
doSomething;
}
在事務(wù)的隔離級別是PROPAGATION_NESTED的時候。
如果調(diào)用方法A诗宣,會開啟一個事務(wù)膘怕,在方法A內(nèi)部調(diào)用方法B,由于方法A已經(jīng)存在開啟尚未提交的事務(wù)召庞,方法B的傳播級別為PROPAGATION_NESTED岛心,會加入這個事務(wù)當(dāng)中,但是在執(zhí)行到方法B之前會創(chuàng)建一個事務(wù)的回滾點(savepoint),然后執(zhí)行方法B篮灼,如果方法B執(zhí)行失敗了忘古,事務(wù)會進行回滾,但是這時指揮回滾到回滾點诅诱,也就是之后回滾B的操作髓堪,外部方法的操作不會回滾;如果B執(zhí)行成功了,接著執(zhí)行A的doSufSomething()方法干旁,如果執(zhí)行出錯驶沼,則會回滾整個事務(wù),也就是doSufSomething()争群、methodB()和doPreSomething()的執(zhí)行都會進行回滾回怜。
如果直接調(diào)用方法B,則會開啟一個事務(wù)换薄,和PROPAGATION_REQUIRED傳播級別一致玉雾。
如果嵌套執(zhí)行的方法要求內(nèi)部方法出錯只回滾自己,外部方法執(zhí)行失敗回滾所有轻要,單獨執(zhí)行時候自動開啟一個執(zhí)行抹凳,則選擇該事物傳播級別。
執(zhí)行邏輯:
開啟事務(wù)
執(zhí)行方法A的doPreSomething
創(chuàng)建回滾點savepoint
執(zhí)行方法B伦腐,失敗只回滾到savepoint
執(zhí)行方法A的doSufSomething
提交或回滾事務(wù)
三赢底、總結(jié)
1、PROPAGATION_REQUIRED
方法 | 是否開啟事務(wù) | 狀態(tài) | 是否回滾 |
---|---|---|---|
doPreSomething | 開啟事務(wù) | 失敗 | 全部回滾 |
methodB | A內(nèi)部直接加入事務(wù)柏蘑,不單獨開啟幸冻,單獨調(diào)用開啟 | 失敗 | 全部回滾 |
doSufSomething | 失敗 | 全部回滾 |
所有方法在同一個事務(wù)中運行,要么一起成功提交事務(wù)咳焚,要么一起回滾事務(wù)洽损,如果單獨執(zhí)行,各自單獨開啟各自事務(wù)革半。
2碑定、PROPAGATION_REQUIRED_NEW
方法 | 是否開啟事務(wù) | 狀態(tài) | 是否回滾 |
---|---|---|---|
doPreSomething | 開啟事務(wù) | 失敗 | 只回滾方法A自己 |
methodB | 開啟事務(wù) | 失敗 | 只回滾方法B自己 |
doSufSomething | 失敗 | 值回滾方法A自己 |
PROPAGATION_REQURIED_NEW所有方法使用各自的事務(wù),各自提交或者回滾各自的事務(wù)又官,相互之間不會造成影響延刘。
如果嵌套執(zhí)行的方法要求各自事務(wù)獨立,不能進行相互影響六敬,則選擇本事務(wù)傳播級別碘赖。
3、PROPAGATION_SUPPORTS|
方法 | 是否開啟事務(wù) | 狀態(tài) | 是否回滾 |
---|---|---|---|
doPreSomething | 開啟事務(wù) | 失敗 | 全部回滾 |
methodB | A內(nèi)部加入事務(wù)不單獨開啟外构,單獨調(diào)用不開啟 | 失敗 | 全部回滾 |
doSufSomething | 失敗 | 全部回滾 |
如果嵌套執(zhí)行的方法要求一起執(zhí)行成功或者一起回滾普泡,單獨執(zhí)行時候以非事務(wù)方式執(zhí)行,則選擇該事物傳播級別审编。
4撼班、PROPAGATION_NOT_SUPPORTED
方法 | 是否開啟事務(wù) | 狀態(tài) | 是否回滾 |
---|---|---|---|
doPreSomething | 開啟事務(wù) | 失敗 | 只回滾A自己 |
methodB | A內(nèi)部掛起A的事務(wù)狀態(tài)執(zhí)行事務(wù)以非,不單獨開啟垒酬,單獨調(diào)用不開啟 | 失敗 | 不做任何回滾 |
doSufSomething | 失敗 | 只回滾A自己 |
如果嵌套執(zhí)行的方法要求內(nèi)部嵌套方法不會對外部方法事務(wù)造成影響并且內(nèi)部方法不需要事務(wù)砰嘁,單獨執(zhí)行時候以非事務(wù)方式執(zhí)行眯亦,則選擇該事物傳播級別。
5般码、PROPAGATION_MANDATORY
方法 | 是否開啟事務(wù) | 狀態(tài) | 是否回滾 |
---|---|---|---|
doPreSomething | 開啟事務(wù) | 失敗 | 全部回滾 |
methodB | A內(nèi)部加入A的事務(wù)妻率,不單獨開啟,單獨調(diào)用跑錯 | 失敗 | 全部回滾 |
doSufSomething | 失敗 | 全部回滾 |
如果嵌套執(zhí)行的方法要求一起執(zhí)行成功或者一起回滾板祝,單獨執(zhí)行時候不允許以非事務(wù)方式執(zhí)行宫静,則選擇該事物傳播級別。
6券时、PROPAGATION_NEVER
方法 | 是否開啟事務(wù) | 狀態(tài) | 是否回滾 |
---|---|---|---|
doPreSomething | 開啟事務(wù) | 失敗 | 全部回滾 |
methodB | A存著事務(wù)直接拋錯孤里,不單獨開啟 | 失敗 | 全部回滾 |
doSufSomething | 失敗 | 全部回滾 |
如果嵌套執(zhí)行的方法要求內(nèi)部方法不允許在事務(wù)中執(zhí)行,單獨執(zhí)行時候必須以非事務(wù)方式執(zhí)行橘洞,則選擇該事物傳播級別捌袜。
7、PROPAGATION_NESTED
方法 | 是否開啟事務(wù) | 狀態(tài) | 是否回滾 |
---|---|---|---|
doPreSomething | 開啟事務(wù) | 失敗 | 全部回滾 |
methodB | A存著事務(wù)就直接加入A事務(wù)炸枣,不存在開啟事務(wù) | 失敗 | 只回滾B自己 |
doSufSomething | 失敗 | 全部回滾 |
如果嵌套執(zhí)行的方法要求內(nèi)部方法出錯只回滾自己虏等,外部方法執(zhí)行失敗回滾所有,單獨執(zhí)行時候自動開啟一個執(zhí)行适肠,則選擇該事物傳播級別霍衫。