Spring @Transactional ——事務回滾


工作原理
運行配置@Transactional注解的測試類的時候,具體會發生如下步驟
1)事務開始時,通過AOP機制,生成一個代理connection對象,並將其放入DataSource實例的某個與DataSourceTransactionManager相關的某處容器中。在接下來的整個事務中,客戶代碼都應該使用該connection連接數據庫,執行所有數據庫命令[不使用該connection連接數據庫執行的數據庫命令,在本事務回滾的時候得不到回滾]
2)事務結束時,回滾在第1步驟中得到的代理connection對象上執行的數據庫命令,然后關閉該代理connection對象


根據上面所述,我們所使用的客戶代碼應該具有如下能力:
1)每次執行數據庫命令的時候
如果在事務的上下文環境中,那么不直接創建新的connection對象,而是嘗試從DataSource實例的某個與DataSourceTransactionManager相關的某處容器中獲取connection對象;在非事務的上下文環境中,直接創建新的connection對象
2)每次執行完數據庫命令的時候
如果在事務的上下文環境中,那么不直接關閉connection對象,因為在整個事務中都需要使用該connection對象,而只是釋放本次數據庫命令對該connection對象的持有;在非事務的上下文環境中,直接關閉該connection對象

 

 

在service類前加上@Transactional,聲明這個service所有方法需要事務管理。每一個業務方法開始時都會打開一個事務。

Spring默認情況下會對運行期例外(RunTimeException)進行事務回滾。這個例外是unchecked

如果遇到checked意外就不回滾。

如何改變默認規則:

1 讓checked例外也回滾:在整個方法前加上 @Transactional(rollbackFor=Exception.class)

2 讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)

3 不需要事務管理的(只查詢的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)

4 如果不添加rollbackFor等屬性,Spring碰到Unchecked Exceptions都會回滾,不僅是RuntimeException,也包括Error。

 

注意: 如果異常被try{}catch{}了,事務就不回滾了,如果想讓事務回滾必須再往外拋try{}catch{throw Exception}。

 


免責聲明!

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



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