0046 @Transactional注解的幾個參數--事務傳播控制--事務隔離級別--異常與回滾


@Transactianal注解有一些屬性,見Spring-Framework-Reference Table17.3 Transactional-settings

@Transactional(propagation=Propagation.REQUIRED)           //控制事務傳播。默認是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT)                //控制事務隔離級別。默認跟數據庫的默認隔離級別相同
@Transactional(readOnly=false)                             //控制事務可讀寫還是只可讀。默認可讀寫
@Transactional(timeout=30)                                 //控制事務的超時時間,單位秒。默認跟數據庫的事務控制系統相同,又說是30秒
@Transactional(rollbackFor=RuntimeException.class)         //控制事務遇到哪些異常才會回滾。默認是RuntimeException
@Transactional(rollbackForClassName=RuntimeException)      //同上
@Transactional(noRollbackFor=NullPointerException.class)   //控制事務遇到哪些異常不會回滾。默認遇到非RuntimeException不會回滾
@Transactional(noRollbackForClassName=NullPointerException)//同上

控制事務傳播----propagation屬性

事務的傳播是指:
    A.f1()有事務X
    B.f2()有事務Y
    當A.f1()調用B.f2()的時候,B.f2()中的代碼執行哪個事務

該屬性可能的值有(以下屬性值加在B.f2()上來理解):

Propagation.NEVER:
    B.f2()不能在任何事務下執行,如果A.f1()調用它,那么拋異常。絕不接受,硬給就拼命

Propagation.NOT_SUPPORTED:
    B.f2()不需要在事務中執行。如果被需要事務X的A.f1()調用,那么事務X被掛起,B.f2()執行完畢X才恢復。不接受,硬給也不收

Propagation.REQUIRES_NEW:
    如果A.f1()調用B.f2(),那么事務X被掛起,重新創建一個事務Y,B.f2()在事務Y中執行,Y執行完畢再繼續X事務。接受,給的不收,用自己的

Propagation.SUPPORTS:
    如果B.f2()被A.f1()調用,那么執行X事務;如果被沒有事務的方法調用,那么就在沒有事務的環境下執行。接受,給就收下,不給也不要

Propagation.REQUIRED:
    如果A.f1()調用B.f2(),那么B.f2()在事務X中執行;如果B.f2()沒有被調用,那就執行自己的事務Y。接受,給就收下,不給就用自己的

Propagation.MANDATORY:
    B.f2()不能開啟自己的事務,只能被開啟了事務的A.f1()調用,如果被沒有開啟事務其他的方法調用,則拋異常。自己沒有,給,必須給,不給就哭

Propagation.NESTED:
    看不懂

控制事務隔離級別----屬性isolation

事務隔離級別是數據庫的概念,在多個事務對一批記錄進行操作的時候,可能出現各種沖突的情況

該屬性的可能值有:
Isolation.READ_UNCOMMITED
    讀未提交
    可以讀到其他事務未提交的數據。導致臟讀(dirty read)

Isolation.READ_COMMITED
    讀已提交。這是很多數據庫的默認隔離級別,但不是MySQL的。
    不能讀到其他事務未提交的數據,只能讀到已提交的數據。解決了臟讀,可導致重讀幻讀
    重讀:在預讀之后,commit之前,其他事務更新了數據,導致兩次讀到的數據不相同
    幻讀:在預讀之后,commit之前,其他事務插入數據,導致兩次讀到的數據條數不相同

Isolation.REPEATABLE_READ
    可重復讀。這是MySQL的默認事務隔離級別
    解決了臟讀,重讀,但依然存在幻讀問題。

Isolation.SERIALIZABLE
    可串行化
    最高的事務隔離級別。解決了臟讀、重讀、幻讀
    但導致大量的超時和鎖競爭。

Isolation.DEFAULT
    數據庫默認隔離級別

只可讀/可讀寫

有的事務不涉及到寫操作,就可以將其指定為只讀事務:@Transactional(readOnly=true),這樣可以節約一些資源開銷
默認是可讀寫

遇到哪些異常會回滾和不回滾----rollbackFor和noRollbackFor屬性

默認在遇到RuntimeException的時候會回滾。

如果要指定在遇到checkedException的時候也回滾
    @Transactional(rollbackFor={IOException.class,FileNoteFoundException})
    多個異常類型,用數組

如果要指定遇到幾個RuntimeException的時候不回滾
    @Transactional(noRollbackFor={NullPointerException.class,IndexOutOfBoundsException.class})
    多個異常類型,用數組
    測試的時候,拋出了Transaction rolled back because it has been marked as rollback-only,暫不知道原因


其他:
@Transaction應當添加在具體的實現類而不是接口上


免責聲明!

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



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