關於PROPAGATION_NESTED的理解


查了一些資料,感覺並不能很清晰地表達出兩者的差異。所以打算自己總結一下。

先來看一下Spring中對於事務傳播性的幾種定義

PROPAGATION_REQUIRED -- 支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
PROPAGATION_SUPPORTS -- 支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY -- 支持當前事務,如果當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW -- 新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED -- 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER -- 以非事務方式執行,如果當前存在事務,則拋出異常。
PROPAGATION_NESTED -- 如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。
前六個策略類似於EJB CMT,第七個(PROPAGATION_NESTED)是Spring所提供的一個特殊變量。
它要求事務管理器或者使用JDBC 3.0 Savepoint API提供嵌套事務行為(如Spring的DataSourceTransactionManager)

其中對於PROPAGATION_REQUIRES_NEW與PROPAGATION_NESTED的理解上有些類似,關鍵在於嵌套事務的理解。

來看一下網上大神對Juergen Hoeller表述的翻譯:

PROPAGATION_REQUIRES_NEW 啟動一個新的, 不依賴於環境的 "內部" 事務. 這個事務將被完全 commited 或 rolled back 而不依賴於外部事務, 它擁有自己的隔離范圍, 自己的鎖, 等等. 當內部事務開始執行時, 外部事務將被掛起, 內務事務結束時, 外部事務將繼續執行. 
    另一方面, PROPAGATION_NESTED 開始一個 "嵌套的" 事務,  它是已經存在事務的一個真正的子事務. 潛套事務開始執行時,  它將取得一個 savepoint. 如果這個嵌套事務失敗, 我們將回滾到此 savepoint. 潛套事務是外部事務的一部分, 只有外部事務結束后它才會被提交. 

那么繪制一個表格來表現他們的差異

定義serviceA.methodA()以PROPAGATION_REQUIRED修飾;
定義serviceB.methodB()以表格中三種方式修飾;
methodA中調用methodB
異常狀態 PROPAGATION_REQUIRES_NEW
(兩個獨立事務) PROPAGATION_NESTED
(B的事務嵌套在A的事務中) PROPAGATION_REQUIRED
(同一個事務)
methodA拋異常
methodB正常 A回滾,B正常提交 A與B一起回滾 A與B一起回滾
methodA正常
methodB拋異常 1.如果A中捕獲B的異常,並沒有繼續向上拋異常,則B先回滾,A再正常提交;
2.如果A未捕獲B的異常,默認則會將B的異常向上拋,則B先回滾,A再回滾 B先回滾,A再正常提交 A與B一起回滾
methodA拋異常
methodB拋異常 B先回滾,A再回滾 A與B一起回滾 A與B一起回滾
methodA正常
methodB正常 B先提交,A再提交 A與B一起提交 A與B一起提交


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM