[轉帖]Spring事務傳播屬性之REQUIRES_NEW用法

https://www.jianshu.com/p/3e9267b025b2

 

@Transactional中可以設置以下7種事務傳播行爲

  1. REQUIRED:支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
  2. SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行。
  3. MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常。
  4. REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。
  5. NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
  6. NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
  7. NESTED:支持當前事務,如果當前事務存在,則執行一個嵌套事務,如果當前沒有事務,就新建一個事務。

通常我們只會用到@Transactional(propagation = Propagation.REQUIRED)在特殊需求的時候需要在一個方法內部提前提交一部分事務或者是讓內部的一段代碼處於單獨的一個事務管理的時候需要用到REQUIRES_NEW

例如下面示例中的methodA需要單獨開啓事務,不受調用方法事務的回滾而回滾:

@transaction    
public void testMethod(){
     dosomethingBefore...
     methodA();
     dosomgthingAfter...
} 

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodA(){
     updateSomething();
} 

假設我們在Controller直接調用testMethod() Spring會幫我們開啓一個事務
運行到methodA()這行的時候會掛起當前事務,然後重新創建一個事務,在methodA()中沒有發生異常的情況下,運行完methodA方法直接提交methodA的事務;後續再執行dosomgthingAfter。

總共會有4種情況:

  • dosomethingBefore發生異常,這時methodA()未運行也就沒有事務,直接回滾testMethod()的事務。
  • updateSomething發生異常,回滾methodA()的事務,此時如果testMethod()對這個異常進行了try catch捕獲,testMethod的事務照常提交。
  • updateSomething發生異常,回滾methodA()的事務,此時如果testMethod()沒有對這個異常進行try catch捕獲,那麼methodA和testMethod的事務都會回滾。
  • 前面全部正常 dosomgthingAfter 發生異常,這時methodA()事務已經提交 testMethod()所做的修改會回滾。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章