javascript
Spring事务传播行为详解
前言
Spring在TransactionDefinition接口中規定了7種類型的事務傳播行為。事務傳播行為是Spring框架獨有的事務增強特性,他不屬于的事務實際提供方數據庫行為。這是Spring為我們提供的強大的工具箱,使用事務傳播行可以為我們的開發工作提供許多便利。但是人們對他的誤解也頗多,你一定也聽過“service方法事務最好不要嵌套”的傳言。要想正確的使用工具首先需要了解工具。本文對七種事務傳播行為做詳細介紹,內容主要代碼示例的方式呈現。
基礎概念
1. 什么是事務傳播行為?
事務傳播行為用來描述由某一個事務傳播行為修飾的方法被嵌套進另一個方法的時事務如何傳播。
用偽代碼說明:
.
代碼中methodA()方法嵌套調用了methodB()方法,methodB()的事務傳播行為由@Transaction(Propagation=XXX)設置決定。這里需要注意的是methodA()并沒有開啟事務,某一個事務傳播行為修飾的方法并不是必須要在開啟事務的外圍方法中調用。
2. Spring中七種事務傳播行為
.
定義非常簡單,也很好理解,下面我們就進入代碼測試部分,驗證我們的理解是否正確。
代碼驗證
文中代碼以傳統三層結構中兩層呈現,即Service和Dao層,由Spring負責依賴注入和注解式事務管理,DAO層由Mybatis實現,你也可以使用任何喜歡的方式,例如,Hibernate,JPA,JDBCTemplate等。數據庫使用的是MySQL數據庫,你也可以使用任何支持事務的數據庫,并不會影響驗證結果。
首先我們在數據庫中創建兩張表:
user1
.
user2
.
然后編寫相應的Bean和DAO層代碼:
User1
.
User2
.
User1Mapper
.
User2Mapper
.
最后也是具體驗證的代碼由service層實現,下面我們分情況列舉。
1.PROPAGATION_REQUIRED
我們為User1Service和User2Service相應方法加上Propagation.REQUIRED屬性。
User1Service方法:
.
User2Service方法:
.
1.1 場景一
此場景外圍方法沒有開啟事務。
驗證方法1:
.
驗證方法2:
.
分別執行驗證方法,結果:
.
結論:通過這兩個方法我們證明了在外圍方法未開啟事務的情況下Propagation.REQUIRED修飾的內部方法會新開啟自己的事務,且開啟的事務相互獨立,互不干擾。
1.2 場景二
外圍方法開啟事務,這個是使用率比較高的場景。
驗證方法1:
.
驗證方法2:
.
驗證方法3:
.
分別執行驗證方法,結果:
.
結論:以上試驗結果我們證明在外圍方法開啟事務的情況下Propagation.REQUIRED修飾的內部方法會加入到外圍方法的事務中,所有Propagation.REQUIRED修飾的內部方法和外圍方法均屬于同一事務,只要一個方法回滾,整個事務均回滾。
2.PROPAGATION_REQUIRES_NEW
我們為User1Service和User2Service相應方法加上Propagation.REQUIRES_NEW屬性。
User1Service方法:
.
User2Service方法:
.
2.1 場景一
外圍方法沒有開啟事務。
驗證方法1:
.
驗證方法2:
.
分別執行驗證方法,結果:
.
結論:通過這兩個方法我們證明了在外圍方法未開啟事務的情況下Propagation.REQUIRES_NEW修飾的內部方法會新開啟自己的事務,且開啟的事務相互獨立,互不干擾。
2.2 場景二
外圍方法開啟事務。
驗證方法1:
.
驗證方法2:
.
驗證方法3:
.
分別執行驗證方法,結果:
.
結論:在外圍方法開啟事務的情況下Propagation.REQUIRES_NEW修飾的內部方法依然會單獨開啟獨立事務,且與外部方法事務也獨立,內部方法之間、內部方法和外部方法事務均相互獨立,互不干擾。
3.PROPAGATION_NESTED
3.1 場景一
此場景外圍方法沒有開啟事務。
驗證方法1:
.
驗證方法2:
.
分別執行驗證方法,結果:
.
結論:通過這兩個方法我們證明了在外圍方法未開啟事務的情況下Propagation.NESTED和Propagation.REQUIRED作用相同,修飾的內部方法都會新開啟自己的事務,且開啟的事務相互獨立,互不干擾。
3.2 場景二
外圍方法開啟事務。
驗證方法1:
.
驗證方法2:
.
驗證方法3:
.
分別執行驗證方法,結果:
.
結論:以上試驗結果我們證明在外圍方法開啟事務的情況下
Propagation.NESTED
修飾的內部方法屬于外部事務的子事務,外圍主事務回滾,子事務一定回滾,而內部子事務可以單獨回滾而不影響外圍主事務和其他子事務
4. REQUIRED,REQUIRES_NEW,NESTED異同
由“1.2 場景二”和“3.2 場景二”對比,我們可知:
NESTED和REQUIRED修飾的內部方法都屬于外圍方法事務,如果外圍方法拋出異常,這兩種方法的事務都會被回滾。但是REQUIRED是加入外圍方法事務,所以和外圍事務同屬于一個事務,一旦REQUIRED事務拋出異常被回滾,外圍方法事務也將被回滾。而NESTED是外圍方法的子事務,有單獨的保存點,所以NESTED方法拋出異常被回滾,不會影響到外圍方法的事務。
由“2.2 場景二”和“3.2 場景二”對比,我們可知:
NESTED和REQUIRES_NEW都可以做到內部方法事務回滾而不影響外圍方法事務。但是因為NESTED是嵌套事務,所以外圍方法回滾之后,作為外圍方法事務的子事務也會被回滾。而REQUIRES_NEW是通過開啟新的事務實現的,內部事務和外圍事務是兩個事務,外圍事務回滾不會影響內部事務。
5. 其他事務傳播行為
鑒于文章篇幅問題,其他事務傳播行為的測試就不在此一一描述了,感興趣的讀者可以去源碼中自己尋找相應測試代碼和結果解釋。
結論
通過上面的介紹,相信大家對Spring事務傳播行為有了更加深入的理解,希望大家有所幫助。
?
from:?https://baijiahao.baidu.com/s?id=1593192556844228644&wfr=spider&for=pc
總結
以上是生活随笔為你收集整理的Spring事务传播行为详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring的7种事务传播行为类型
- 下一篇: 浅析Spring事务传播行为和隔离级别