Spring Boot中Service用@Transactional 注解


 

一般來說function2和function1用的是同一個Transaction。

這個取決於@Transactional 的 propagation設置(事務的傳播性)

默認的是

1
@Transactional (propagation=propagation.REQUIRED)

也就是使用同一個Transaction。也可以按需求設置成 NESTED 或者 REQUIRES_NEW。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//in A.java
Class A {
     @Transactional (propagation=propagation.REQUIRED)
     public  void  aMethod {
         B b =  new  B();
         b.bMethod();
     }
}
  
//in B.java
Class B {
     @Transactional (propagation=propagation.REQUIRED)
     public  void  bMethod {  //something }
}
在上面這個例子中,傳播性被設為了REQUIRED,注意,這是默認值,也即不進行該參數配置等於配置成REQUIRED。

  REQUIRED的含義是,支持當前已經存在的事務,如果還沒有事務,就創建一個新事務。在上面這個例子中,假設調用aMethod前不存在任何事務,那么執行aMethod時會自動開啟一個事務,而由aMethod調用bMethod時,由於事務已經存在,因此會使用已經存在的事務(也就是執行aMethod之前創建的那個事務)。

  對於這樣的配置,如果bMethod過程中發生異常需要回滾,那么aMethod中所進行的所有數據庫操作也將同時被回滾,因為這兩個方法使用了同一個事務。

  MANDATORY的含義是,支持當前已經存在的事務,如果還沒有事務,就拋出一個異常。如果上例中aMethod的傳播性配置為MANDATORY,我們就無法在沒有事務的情況下調用aMethod,因此,傳播性為MANDATORY的方法必定是一個其他事務的子事務,當邏輯上獨立存在沒有意義或者可能違反數據、事務完整性的時候,就可以考慮設置這樣的傳播性設置。

  NESTED的含義是,在當前事務中創建一個嵌套事務,如果還沒有事務,那么就簡單地創建一個新事務。

  REQUIRES_NEW的含義是,掛起當前事務,創建一個新事務,如果還沒有事務,就簡單地創建一個新事務。

  請注意以上兩者的區別,大多數情況下一上兩種傳播性行為是類似的,不過在事務回滾的問題上,以上兩者有很大的區別。

  首先,REQUIRES_NEW會創建一個與原事務無關的新事務,盡管是由一個事務調用了另一個事務,但卻沒有父子關系。

  如果bMethod的傳播性是REQUIRES_NEW,而拋出了一個異常,則bMethod一定會被回滾,而如果aMethod捕獲並處理了這個bMethod拋出的異常,那么aMethod仍有可能成功提交。當然,如果aMethod沒有處理這個異常,那么aMethod也會被回滾。

  如果aMethod在bMethod完成后出現了異常,那么bMethod已經提交而無法回滾,只有aMethod被回滾了。

  而對於NESTED,雖然也會創建一個新事務,但是這個事務與調用者是有父子關系的相互依存的。

  如果bMethod的傳播性是NESTED,而拋出了一個異常,事務的回滾行為與REQUIRES_NEW是一致的。

  但是如果aMethod在bMethod完成后出現了異常,bMethod同樣也會被回滾。因為事實上,EJB中沒有對於NESTED傳播性的類似實現,NESTED並不是真正啟動了一個事務,而是開啟了一個新的savepoint。

  NEVER的含義很簡單,就是強制要求不在事務中運行,如果當前存在一個事務,則拋出異常,因此如果bMethod傳播性是NEVER,則一定拋出異常。

  NOT_SUPPORTED的含義是,強制不在事務中運行,如果當前存在一個事務,則掛起該事務。

  SUPPORTS的含義是,支持當前事務,如果沒有事務那么就不在事務中運行。SUPPORTS傳播性的邏輯含義比較模糊,因此一般是不推薦使用的。


免責聲明!

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



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