當調用方不存在事務的時候,二者的效果是一致的。因此這裏討論問題的前提是調用方存在事務。PROPAGATION_REQUIRES_NEW 啓動一個新的, 不依賴於環境的 "內部" 事務. 這個事務將被徹底 commited 或 rolled back 而不依賴於外部事務, 它擁有本身的隔離範圍, 本身的鎖, 等等. 當內部事務開始執行時, 外部事務將被掛起, 內務事務結束時, 外部事務將繼續執行.
另外一方面, PROPAGATION_NESTED 開始一個 "嵌套的" 事務, 它是已經存在事務的一個真正的子事務. 潛套事務開始執行時, 它將取得一個 savepoint. 若是這個嵌套事務失敗, 咱們將回滾到此 savepoint. 潛套事務是外部事務的一部分, 只有外部事務結束後它纔會被提交.
因而可知, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大區別在於, PROPAGATION_REQUIRES_NEW 徹底是一個新的事務, 而 PROPAGATION_NESTED 則是外部事務的子事務, 若是外部事務 commit, 嵌套事務也會被 commit, 這個規則一樣適用於 roll back. spring
1.調用方和被調用方屬於同一個component,被調用方的 @Transacational註解無效sql
package com.transacational; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; /** * Created by chenqimiao on 17/10/31. */ @Component public class Service { public void test1(){ test2(); } @Transactional//此處的註解無效 public void test2(){ } }
2.被調用方不是一個public方法,被調用方的 @Transacational註解無效 app
@Component public class Service { @Resource private Service1 service1; public void test1(){ test2(); service1.test3(); } @Transactional//1.此處的註解無效 public void test2(){ } }
package com.transacational; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; /** * Created by chenqimiao on 17/10/31. */ @Component public class Service1 { @Transactional//2.此處註解無效 protected void test3(){ } }
3.未開啓事務開關,如:在SpringBoot中,啓動類未使用 @EnableTransactionManagementspa
timeout是一個供開發者設置超時時間的屬性。默認值-1,超時時間由具體的sql系統決定。 code
/** * Created by chenqimiao on 17/10/31. */ @Component public class Service3 { @Resource private AdminInfoDoMapper adminInfoDoMapper; @Transactional(timeout = 4)//並不會超時 public void test4(){ adminInfoDoMapper.selectNameById(1); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } }
超時時間具體的定義:事務開始(在該方法第一句代碼執行以前)到最後一個Statement執行完畢component
因此象下面這樣寫,事務就會超時blog
@Component public class Service3 { @Resource private AdminInfoDoMapper adminInfoDoMapper; @Transactional(timeout = 4) public void test4(){ try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } adminInfoDoMapper.selectNameById(1); } }
默認狀況下,只有當RuntimeException或其子類的異常被事務捕獲以後,事務纔會回滾,若是要讓事務可以回滾全部異常,必須手動指定 @Transactional(rollbackFor=Exception.class) ,這樣繼承Exception的子類或者Exception自己均可以讓事務回滾。繼承