背景
Spring 默認的事務(wù)的傳播為PROPAGATION_REQUIRED即如果當前沒有事務(wù)苔严,就新建一個事務(wù)刀荒。
我們知道首懈,如果一個事物函數(shù)拋出異常會回滾看成,那么對于兩個獨立的事物如果里面函數(shù)拋出異常怎么辦华畏?
兩個兩個獨立的事物如果內(nèi)層事務(wù)失敗拋出異常內(nèi)層肯定回滾鹏秋,但是外層怎么辦?
而這篇博客就是對Spring傳播特點進行詳細描述亡笑。
Spring事物傳播具體使用場景
public void addUser()
{
}
public void createTransaction()
{
addUser();
}
事物傳播機制描述的就是當我createTransaction()時候侣夷,由于createTransaction()和addUser()都帶有事物,那么這兩個事物的關(guān)系式怎么樣仑乌,如果是強關(guān)系就是在同一個事物里百拓,這樣當addUser()拋異常的時候會退回到調(diào)用creatTransaction()函數(shù)之前。
這兩者之間會有什么樣場景呢晰甚?這就是考察我們考慮全面性及其自己的產(chǎn)品設(shè)計能力⊙么現(xiàn)在大概想到的會有如下的場景:
1).addUser()分為 處于事物里 inTran1,不在事物里 notTran1.
2).createTransaction() 也有處于事物里 inTran2厕九,不在事物里notTran2
兩兩組合起來就是4種組合場景蓖捶,而這4種組合場景會有不同的表現(xiàn)。
其表現(xiàn)形式會有幾種:
a).拋出異常
b).正常
C).掛起
幾個事物傳播機制具體描述
1).不管使用事物與否扁远,我就使用上層函數(shù)的特性俊鱼,而上層函數(shù)會有事物和無事物。
如果PROPAGATION_NEVER 以非事務(wù)方式執(zhí)行畅买,如果當前存在事務(wù)并闲,則拋出異常。
PROPAGATION_MANDATORY 使用當前的事務(wù)谷羞,如果當前沒有事務(wù)帝火,就拋出異常。
2).require 描述需要 建事物
隨意綁定關(guān)系:PROPAGATION_REQUIRED,有就在一起沒有就自己建一個犀填。
我任性我每次都創(chuàng)建:PROPAGATION_REQUIRES_NEW 每次總是新建事務(wù)蠢壹,如果當前存在事務(wù),把當前事務(wù)掛起宏浩。
3).support 描述支持與否(不會新建)知残,是以事物方式執(zhí)行還是非事物方式執(zhí)行,不會新建
PROPAGATION_SUPPORTS 支持當前事務(wù)比庄,如果當前沒有事務(wù)求妹,就以非事務(wù)方式執(zhí)行。
PROPAGATION_NOT_SUPPORTS 以非事務(wù)方式執(zhí)行操作佳窑,如果當前存在事務(wù)制恍,就把當前事務(wù)掛起。
4).統(tǒng)一提交但是不統(tǒng)一回滾
PROPAGATION_NESTED
理解Nested的關(guān)鍵是savepoint神凑。他與PROPAGATION_REQUIRES_NEW的區(qū)別是净神,PROPAGATION_REQUIRES_NEW另起一個事務(wù),將會與他的父事務(wù)相互獨立溉委,
而Nested的事務(wù)和他的父事務(wù)是相依的鹃唯,他的提交是要等和他的父事務(wù)一塊提交的。也就是說瓣喊,如果父事務(wù)最后回滾坡慌,他也要回滾的。
但是內(nèi)部事務(wù)的回滾不會對外部事務(wù)造成影響藻三。它只對DataSourceTransactionManager事務(wù)管理器起效洪橘。
從回滾的角度來講 事物的特性
如果同一事物的話,子函數(shù)出錯棵帽,子父函數(shù)一同回滾熄求,比如PROPAGATION_REQUIRED,PROPAGATION_MANDATORY逗概,PROPAGATION_SUPPORT
如果父函數(shù)失敗弟晚,我也想子回滾怎么辦,答案是使用PROPAGATION_NESTED仗谆。 嵌套的含義是兩個不同的事物但是父對子有影響指巡。它將創(chuàng)建一個依賴于外層事務(wù)的子事務(wù),當外層事務(wù)提交或回滾時隶垮,子事務(wù)也會連帶提交和回滾。
如果我想子父函數(shù)在事物上沒有關(guān)系怎么辦秘噪?PROPAGATION_REQUIRES_NEW 將創(chuàng)建一個全新的事務(wù)狸吞,它和外層事務(wù)沒有任何關(guān)系。
寫在后面的話
以前看了Spring 幾個傳播機制老想去記,但是今天突然想到設(shè)計者是怎么設(shè)計它的肯定是根據(jù)具體場景來劃分這些傳播層次蹋偏,而這些層次劃分都是依據(jù)關(guān)系而定的便斥。
另外不明白Spring為什么搞這么多傳播機制,我們寫代碼暫時只關(guān)心同一個事物還是不同一個事物威始,同一個事物就可以一起回滾不會出現(xiàn)臟數(shù)據(jù)枢纠。
Spring的默認傳播機制是PROPAGATION_REQUIRES。