Spring 事務傳播行為的使用


                                                                                                                           Spring 事務傳播行為的使用

★關鍵日志

  事務提交日志:
    Transaction synchronization committing SqlSession
    Transaction synchronization deregistering SqlSession
    Transaction synchronization closing SqlSession
       事務回滾日志:
    Transaction synchronization resuming SqlSession
    Transaction synchronization deregistering SqlSession
    Transaction synchronization closing SqlSession

 

PROPAGATION詳解

    不加事務:支持當前事務,如果沒有事務就以非事務方式運行。

    PROPAGATION_REQUIRED -- 支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

    PROPAGATION_SUPPORTS -- 支持當前事務(即能查詢到update或insert,但是沒有提交的東西--事務方法都是等方法執行完才提交), 如果當前沒有事務,就以非事務方式執行。(在類中不加注解的情況下和不加事務是一樣的,類中加了注解就可以加此注解來實現不加注解的情況)

    PROPAGATION_NOT_SUPPORTED -- 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

    PROPAGATION_NEVER -- 以非事務方式執行,如果當前存在事務,則拋出異常。


    PROPAGATION_MANDATORY -- 支持當前事務,如果當前沒有事務,就拋出異常。

    PROPAGATION_REQUIRES_NEW -- 新建事務,如果當前存在事務,把當前事務掛起。


    PROPAGATION_NESTED -- 如果當前存在事務,則在嵌套事務內執行,如果執行失敗,內部事務(即 ServiceB#methodB) 將回滾到它執行前的 SavePoint(回滾本身)。

                                                              如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。

 

事務及嵌套事務的理解:


    1.Propagation.REQUIRED:同一個事務,一起成功或失敗。注意:REQUIRED方法內的事務方法,不應該try-catch 而不拋出異常。


    2.Propagation.REQUIRES_NEW:完全是新的事務,回滾或提交不受外部影響。


    3.Propagation.NESTED的嵌套事務理解 :
      (1)回滾只是回滾內部方法本身,外部事務可以選擇回滾/提交(try-catch方式處理的不同處理)
        PS:這點Propagation.REQUIRES_NEW也能做到。

      (2)外部事務提交回滾/提交,它也進行回滾/提交(它成功時的提交是在外部事務提交時)。
        PS:這點Propagation.REQUIRES_NEW做不到。

 

異常:Transaction rolled back because it has been marked as rollback-only原因


    1.捕獲后又拋出了不回滾的異常(默認RuntimeException才回滾,而Exception不回滾)。


    2.Propagation.REQUIRED A方法調用 Propagation.REQUIRED B方法,如果捕獲了B方法中的異常沒有拋出 或 捕獲后又拋出了不回滾的異常(默認Exception不回滾)。

 

Transactional的不回滾問題

    1、檢查你方法是不是public的,public方法的Transactional注解才是有效的,才能控制事務。

    2、Spring默認只對UnChecked異常(RuntimeException)回滾,對於Checked(Exception)異常不回滾。
      你的異常類型是Checked異常。如果想check異常也想回滾怎么辦? 
    (1)注解上加rollbackFor=Exception.class
    (2)對異常進行轉換,轉換成RuntimeException或自定義繼承RuntimeException的異常

    3. 同一個類中的方法調用,內部方法的事務是沒有效果的。
      如方法A沒加事務,方法B中加了事務(不管加的是什么類型的事務)。方法A調用方法B,這樣方法B中的事務是無效的。因為AOP只對A方法進行處理了,而不會對內部的B方法進行處理。

 

父類中加了Transactional注解,子類中會繼承。


  現象:service層繼承了CommonSercice的方法默認。CommonSercice加了transaction注解,結果service層的每個方法都默認有了transaction注解(required)。

 


項目實踐(不一定遵守,怎么方便怎么用)


    1.不在類中加@Transactional,只在用到的方法中加。


    2.不用PROPAGATION_SUPPORTS,因為效果和不加是一樣的。


    3.大多數事務:PROPAGATION_REQUIRED即可滿足要求,要有rollbackFor=Exception.class,格式統一如下:
      @Transactional(propagation = Propagation.REQUIRED,rollbackFor=Exception.class)

 


免責聲明!

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



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