譬如朝露,去日苦多
事務(wù)傳播行為: Propagation [?pr?p?'ɡe??(?)n]
spring 給我們提供了7大傳播行為程癌;我們打開org.springframework.transaction.annotation.Propagation類源碼可以分別看到這7種:
這里提出一個(gè)概念村视,方便下面的理解
- 調(diào)用者方法
- 被調(diào)用者方法
事務(wù)的傳播行為指的是:當(dāng)事務(wù)方法嵌套調(diào)用時(shí)涮坐, 調(diào)用者事務(wù)
和被調(diào)用者事務(wù)
沖突的解決方案焰雕。spring為我們提供了7種解決方案
支持調(diào)用者事務(wù)
required [r??kwa??rd]
(必須的)
這是spring默認(rèn)的事務(wù)傳播行為
申明在被調(diào)用者上舵变,調(diào)用者沒有開啟事務(wù)记焊,則被調(diào)用者開啟事務(wù)逸月;調(diào)用者有開啟事務(wù),則被調(diào)用者加入調(diào)用者事務(wù)遍膜。即
優(yōu)先使用調(diào)用者事務(wù)
,此時(shí)內(nèi)部出現(xiàn)異惩胗玻回滾會(huì)使外部調(diào)用者事務(wù)方法也回滾申明在調(diào)用者上,會(huì)創(chuàng)建新事務(wù)
就好像在公司遇到前端的樣式問題一樣瓢颅,前端在就找前端解決恩尾,不在就自己解決
@Transactional(propagation=Propagation.REQUIRED)
supports
(支持)
本身不會(huì)創(chuàng)建事務(wù)
- 申明在被調(diào)用者上,調(diào)用者沒有開啟事務(wù)挽懦,則被調(diào)用者方法就是一個(gè)不帶事務(wù)的方法翰意。調(diào)用者有開啟事務(wù),則被調(diào)用者加入調(diào)用者事務(wù)
- 申明在調(diào)用者上信柿,當(dāng)前方法以非事務(wù)方式運(yùn)行
就像遇到前端問題冀偶,就把問題忽略。不去解決
@Transactional(propagation=Propagation.SUPPORTS)
mandatory [?m?nd?t??ri]
(強(qiáng)制)
本身不會(huì)創(chuàng)建事務(wù)
- 申明在被調(diào)用者上渔嚷,當(dāng)前方法必須使用
調(diào)用者的事務(wù)
进鸠,如果調(diào)用者有事務(wù),就加入形病。如果沒有就拋出IllegalTransactionStateException異常 - 申明在調(diào)用者上堤如,報(bào)異常IllegalTransactionStateException
就像遇到了比較難以解決的前端問題。前端不在窒朋,自己也解決不了
@Transactional(propagation=Propagation.MANDATORY)
不支持調(diào)用者事務(wù)
requires_new
(隔離)
- 申明在被調(diào)用者上搀罢,不管調(diào)用者是否使用事務(wù)會(huì)都創(chuàng)建一個(gè)新的事務(wù),調(diào)用者中的事務(wù)掛起侥猩,等到被調(diào)用者事務(wù)執(zhí)行完畢榔至,繼續(xù)執(zhí)行調(diào)用者中的事務(wù)。
一般局部數(shù)據(jù)操作一致性都用此方法欺劳。
- 申明在調(diào)用者上唧取,會(huì)創(chuàng)建新事務(wù)
@Transactional(propagation=Propagation.REQUIRES_NEW)
not_supported
(不支持)
本身不會(huì)創(chuàng)建事務(wù)。
- 申明在被調(diào)用者上方法上划提。調(diào)用者事務(wù)方法調(diào)用此方法時(shí)枫弟,事務(wù)不會(huì)進(jìn)到此方法。即把外部事務(wù)掛起鹏往,直到此方法執(zhí)行完后恢復(fù)外部事務(wù)淡诗。
- 申明在調(diào)用者上,當(dāng)前方法以非事務(wù)方式運(yùn)行
@Transactional(propagation=Propagation.NOT_SUPPORTED)
never
(強(qiáng)制非事務(wù))
本身不會(huì)創(chuàng)建事務(wù)。
- 申明在被調(diào)用者方法上韩容,調(diào)用者方法上使用了事務(wù)則報(bào)IllegalTransactionStateException
異常 - 申明在調(diào)用者上款违,當(dāng)前方法以非事務(wù)方式運(yùn)行
@Transactional(propagation=Propagation.NEVER)
嵌套事務(wù)
nested [?nest?d]
(嵌套事務(wù))
開始一個(gè) "嵌套的" 事務(wù), 它是已經(jīng)存在事務(wù)的一個(gè)真正的子事務(wù)。嵌套事務(wù)開始執(zhí)行時(shí), 它將取得一個(gè) savepoint群凶。 如果這個(gè)嵌套事務(wù)失敗, 我們將回滾到此 savepoint插爹。嵌套事務(wù)是外部事務(wù)的一部分, 只有外部事務(wù)結(jié)束后它才會(huì)被提交。
@Transactional(propagation= Propagation.NESTED)
我對(duì)事務(wù)傳播行為的個(gè)人理解
事務(wù)總是沿著方法的調(diào)用方向來傳播的
请梢,A方法調(diào)用B方法赠尾,A方法的事務(wù)可能會(huì)傳播給B方法。不存在B方法事務(wù)傳播給A方法毅弧!具體分為下面幾種情況:
A創(chuàng)建了事務(wù)气嫁,并將事務(wù)傳播給B。兩者使用同一事務(wù)
A創(chuàng)建了事務(wù)形真,B也創(chuàng)建了事務(wù)杉编。兩者隔離執(zhí)行
A創(chuàng)建了事務(wù)超全,B無事務(wù)運(yùn)行
A無事務(wù)運(yùn)行咆霜,B創(chuàng)建事務(wù)
A無事務(wù)運(yùn)行,B無事務(wù)運(yùn)行
為了深入理解事務(wù)的傳播行為嘶朱,我對(duì)之做了實(shí)驗(yàn)蛾坯。這篇文章有記錄
http://www.reibang.com/p/bc3cbacf9e70