Spring事務傳播屬性介紹(三).Nested


Required、Required_New傳播屬性分析傳送門:https://www.cnblogs.com/lvbinbin2yujie/p/10259897.html

Mandatory、Never、Not_Support傳播屬性分析傳送門:https://www.cnblogs.com/lvbinbin2yujie/p/10260030.html

我的Spring事務傳播屬性介紹比較傳送門:https://files.cnblogs.com/files/lvbinbin2yujie/Spring_Tx_Note.rar

 

Spring事務傳播屬性Nested

         說明:如果有事務運行,就作為這個事務的嵌套事務運行; 如果沒有事務運行,新建一個事務運行;

 

首先要說的,Nested類型事務測試時候使用DataSourceTransactionManager作為事務管理器,DataSourceTransactionManager只對jdbcTemplate、ibatis有效;且需要支持JDBC3.0才起作用

ServiceA.java文件

 

 

ServiceB.java文件

 

ServiceA中的testNest方法本身是個事務;testNest操作了jdbcTemplate寫入一條數據,另外ServiceB的三個NESTED方法分別寫入一條記錄,不過最后一個方法手動模擬拋出了異常;

 

測試Main方法:

 

 

執行之后查看數據庫結果: serviceBNest3方法一定寫入過青雉,但是回滾了記錄;最終testNest方法也成功提交了; 注意的是, 三個Nested方法一定要try-catch,不然testNest的記錄都會回滾,Nested方法也沒意義了;   try-catch包圍住NESTED方法,是為了保證NESTED方法執行失敗不干擾到該方法以外執行的操作的正常提交回滾 ; 每一個NESTED方法開始可以看做是一個SavePoint點,執行失敗,就會回滾到該方法開始的地方;

 

 

修改下ServiceA.java文件

 

執行測試方法:  發現數據庫一條記錄都不存在

原因分析: 外層事務回滾,內層嵌套事務會全部回滾;

 

NESTED和REQUIRED_NEW的區別:

  1. 假設都是在一個REQUIRED類型的事務里調用這些事務,就像上面的例子,該REQUIRED類型方法調用拋出異常,REQUIRED_NEW的方法仍然可以提交,但是NESTED還要受到REQUIRED事務回滾而被迫回滾; 這就是我認為的新的事務與內嵌事務的區別;
  2. 假設都是在一個REQUIRED類型的事務里調用這些事務方法,REQUIRED_NEW和NESTED都拋出異常的情況下,外層事務不寫try-catch,都會導致該REQUIRED類型事務全部回滾.  REQUIRED_NEW和NESTED調用處寫了try-catch塊,外層可以正常提交 ; 但是REQUIRED類型的外層即使寫了Try-catch塊,也會拋出異常: Transaction rolled back because it has been marked as rollback-only

 

查看源碼的時候,又意識到一個問題:

  ServiceA.java文件

 

 ServiceB.java文件

 

說明: 當全局事務ReadOly為true的時候,ServiceB的方法為NESTED類型,即使ServiceB不執行數據庫增刪改操作,同樣會拋出異常;

Connection is read-only. Queries leading to data modification are not allowed.

原因分析:因為NESTED事務是采用JDBC3.0的SavePoint進行回滾事務,只讀的Connection創建回滾點就會拋出該異常;關於該異常具體信息我也不甚了解。同樣的,只讀事務即使不使用NESTED事務,如果進行增刪改操作,也會拋出異常

Connection is read-only. Queries leading to data modification are not allowed.

 


免責聲明!

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



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