Spring中聲明式事務的注解@Transactional的參數的總結(REQUIRED和REQUIRES_NEW的與主方法的回滾問題)


一、事務的傳播行為
1.介紹

當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啟一個新事務,並在自己的事務中運行。
2.屬性

事務的傳播行為可以由傳播屬性指定。Spring定義了7種類傳播行為。


系統默認的是REQUIRED屬性。
常用的是REQUIRED和REQUIRES_NEW,所以此處只說明這兩種屬性。
下面先看系統默認的REQUIRED屬性。


purchase代表兩個聲明了事務的方法,並且傳播行為是系統的默認行為。同時checkout也是一個聲明了事務的方法,在該方法中調用前述的兩個方法。當checkout執行到第一個方法的時候,第一個方法繼續使用checkout的事務進行執行,第二個方法一樣,所以整個方法只有一個事務。

下面介紹REQUIRES_NEW屬性。

方法含義和上述一樣,知識兩個子方法的傳播屬性均為REQUIRES_NEW。主方法的事務tx1執行到第一個方法的時候,掛起,然后子方法的事務進行,第二個方法類似。


如果一個事務發生了錯誤,那么回滾。所以REQUIRED屬性中,如果第二個方法發生錯誤,第一個方法也會回滾,然而REQUIRES_NEW屬性中,第二個方法發生錯誤,因為第一個是單獨的事務,所以不會受到影響。

那么,如果兩個混合使用呢?
(為簡單起見,REQUIRED在下述表達稱為系統默認,REQUIRES_NEW稱為new)
現在測試第一種方法的屬性為系統默認,第二種方法為new,第二種方法出現錯誤。此時結果是方法1也回滾。但是按照前面的理解,方法2是單獨的事務,應該只造成自己回滾,為什么第一種方法也會回滾?

第一種方法發生錯誤后,產生錯誤造成本身回滾,但是他的異常因為沒有捕獲,所以傳到了主方法的事務中,主方法的事務出現錯誤,所以回滾,第一個方法在主方法的事務中,所以第一個方法的SQL語句會回滾!
下面用一個簡圖總結一下:


如果第一種方法為new,第二種方法為系統默認,那么第二種發生錯誤后,主方法的事務回滾,然后第一種方法是自己的事務,所以不受影響,不回回滾,第一個方法的SQL語句就會執行。道理雷同,就不再畫圖表示。


免責聲明!

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



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