@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應當添加在具體的實現類而不是接口上