Spring嵌套事務解惑(重點)

http://www.iteye.com/topic/35907ui

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的DataSourceTransactionManagerspa

 PROPAGATION_REQUIRES_NEW 啓動一個新的, 不依賴於環境的 "內部" 事務. 這個事務將被徹底 commited 或 rolled back 而不依賴於外部事務, 它擁有本身的隔離範圍, 本身的鎖, 等等. 當內部事務開始執行時, 外部事務將被掛起, 內務事務結束時, 外部事務將繼續執行.
  另外一方面, PROPAGATION_NESTED 開始一個 "嵌套的" 事務,  它是已經存在事務的一個真正的子事務. 潛套事務開始執行時,  它將取得一個 savepoint. 若是這個嵌套事務失敗, 咱們將回滾到此 savepoint. 潛套事務是外部事務的一部分, 只有外部事務結束後它纔會被提交. 事務

PROPAGATION_REQUIRES_NEW 啓動一個新的, 不依賴於環境的 "內部" 事務. 這個事務將被徹底 commited 或 rolled back 而不依賴於外部事務, 它擁有本身的隔離範圍, 本身的鎖, 等等. 當內部事務開始執行時, 外部事務將被掛起, 內務事務結束時, 外部事務將繼續執行. 
  另外一方面, PROPAGATION_NESTED 開始一個 "嵌套的" 事務,  它是已經存在事務的一個真正的子事務. 潛套事務開始執行時,  它將取得一個 savepoint. 若是這個嵌套事務失敗, 咱們將回滾到此 savepoint. 潛套事務是外部事務的一部分, 只有外部事務結束後它纔會被提交. 
  因而可知, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大區別在於, PROPAGATION_REQUIRES_NEW 徹底是一個新的事務, 而 PROPAGATION_NESTED 則是外部事務的子事務, 若是外部事務 commit, 潛套事務也會被 commit, 這個規則一樣適用於 roll back. get

  因而可知,it

PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大區別在於,io

PROPAGATION_REQUIRES_NEW 徹底是一個新的事務, 而require

PROPAGATION_NESTED 則是外部事務的子事務, 若是外部事務 commit, 潛套事務也會被 commit,變量

這個規則一樣適用於 roll back. 配置

固然, 就算全部嵌套事務都已經成功, 外部事務仍是可能由於嵌套事務的執行結果而致使失敗,  此時整個事務都要 roll back ,這也是嵌套事務的重要特性之一, 即外部事務和嵌套事務互相影響程序

只有須要根據子事務的執行狀況進行分支處理的狀況下才是nested的用武之地, savepoint是嵌套事務回滾的實現方式 須要注意的是使用它的限制條件

使用嵌套事務是有前提的,就是該嵌套事務可能須要作分支處理。不然用 PROPAGATION_REQUIRED 就足夠了,若是子事務有異常,直接回滾。

nested 能夠在外層rollback全部內層的事務。requiresnew 不行。

例子:

  1. ServiceA {  
  2.       
  3.     /** 
  4.      * 事務屬性配置爲 PROPAGATION_REQUIRED 
  5.      */  
  6.     void methodA() {  
  7.         ServiceB.methodB();  
  8.     }  
  9.   
  10. }  
  11.   
  12. ServiceB {  
  13.       
  14.     /** 
  15.      * 事務屬性配置爲 PROPAGATION_REQUIRES_NEW 
  16.      */   
  17.     void methodB() {  
  18.     }  
  19.       
  20. }     

 

PROPAGATION_REQUIRES_NEW 時 ServiceB.methodB 沒辦法回滾到它執行以前的 SavePoint, 這時已經產生了一些髒數據, 而這些髒數據將可能致使後面的程序執行出錯

 

  1. ServiceA {  
  2.       
  3.     /** 
  4.      * 事務屬性配置爲 PROPAGATION_REQUIRED 
  5.      */  
  6.     void methodA() {  
  7.         try{
  8.         ServiceB.methodB();  
  9.         }catch(Exeception e){
  10.          ServiceC.methodC();
  11.        }
  12.     }  
  13.   
  14. }  
  15.   
  16. ServiceB {  
  17.       
  18.     /** 
  19.      * 事務屬性配置爲 PROPAGATION_NESTED 
  20.      */   
  21.     void methodB() {  
  22.     }  
  23.       
  24. }     

對於PROPAGATION_NESTED 的嵌套事務而言,若是 ServiceB.methodB()異常,會會回滾到上一個savepoint點,外層事務A,能夠捕獲,處理ServiceC.methodC(),可是對於ServiceA.methodA()異常,會回滾整個嵌套的事務

相關文章
相關標籤/搜索