亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

詳解Spring中的Transactional屬性

瀏覽:71日期:2023-07-14 15:11:57
目錄一、Transactional二、使用說明三、注解失效問題一、Transactional

聲明式事務管理建立在AOP之上的。其本質是對方法前后進行攔截,然后在目標方法開始之前創建或者加入一個事務,在執行完目標方法之后根據執行情況提交或者回滾事務。

簡而言之,@Transactional注解在代碼執行出錯的時候能夠進行事務的回滾。

詳解Spring中的Transactional屬性

二、使用說明

詳解Spring中的Transactional屬性

在啟動類上添加@EnableTransactionManagement注解。 用于類上時,該類的所有 public 方法將都具有該類型的事務屬性,同時,我們也可以在方法級別使用該標注來覆蓋類級別的定義。 在項目中,@Transactional(rollbackFor=Exception.class),如果類加了這個注解,那么這個類里面的方法拋出異常,就會回滾,數據庫里面的數據也會回滾。 在@Transactional注解中如果不配置rollbackFor屬性,那么事物只會在遇到RuntimeException的時候才會回滾,加上rollbackFor=Exception.class,可以讓事物在遇到非運行時異常時也回滾。

而至于什么是運行時異常(RuntimeException),什么是非運行時異常,可通過下圖所示理解(圖片截取網絡)

詳解Spring中的Transactional屬性

三、注解失效問題

正常情況下,只要在方法上添加@Transactional注解就完事了,但是需要注意的是,雖然使用簡單,但是如果不合理地使用注解,還是會存在注解失效的問題。

@Transactional 應用在非 public 修飾的方法上

事務攔截器在目標方法執行前后進行攔截,內部會調用方法來獲取Transactional 注解的事務配置信息,調用前會檢查目標方法的修飾符是否為 public,不是 public則不會獲取@Transactional 的屬性配置信息。

@Transactional 注解屬性 rollbackFor 設置錯誤

rollbackFor 可以指定能夠觸發事務回滾的異常類型。Spring默認拋出了未檢查unchecked異常(繼承自 RuntimeException 的異常)或者 Error才回滾事務;其他異常不會觸發回滾事務。如果在事務中拋出其他類型的異常,但卻期望 Spring 能夠回滾事務,就需要指定rollbackFor屬性。

同一個類中方法調用,導致@Transactional失效

開發中避免不了會對同一個類里面的方法調用,比如有一個類Test,它的一個方法A,A再調用本類的方法B(不論方法B是用public還是private修飾),但方法A沒有聲明注解事務,而B方法有。則外部調用方法A之后,方法B的事務是不會起作用的。這也是經常犯錯誤的一個地方。那為啥會出現這種情況?其實這還是由于使用Spring AOP代理造成的,因為只有當事務方法被當前類以外的代碼調用時,才會由Spring生成的代理對象來管理。

異常被你的 catch“吃了”導致@Transactional失效

如果你手動的catch捕獲這個異常并進行處理,事務管理器會認為當前事務應該正常commit,就會導致注解失效,如果非要捕獲且不失效,就必須在代碼塊內throw new Exception拋出異常。

數據庫引擎不支持事務

開啟事務的前提就是需要數據庫的支持,我們一般使用的Mysql引擎時支持事務的,所以一般不會出現這種問題。

開啟多線程任務時,事務管理會受到影響

因為線程不屬于spring托管,故線程不能夠默認使用spring的事務,也不能獲取spring注入的bean在被spring聲明式事務管理的方法內開啟多線程,多線程內的方法不被事務控制。如下代碼,線程內調用insert方法,spring不會把insert方法加入事務就算在insert方法上加入@Transactional注解,也不起作用。

@Service public class ServiceA { @Transactional public void threadMethod(){ this.insert(); System.out.println('main insert is over'); for(int a=0 ;a<3;a++){ ThreadOperation threadOperation= new ThreadOperation(); Thread innerThread = new Thread(threadOperation); innerThread.start(); } } public class ThreadOperation implements Runnable { public ThreadOperation(){ } @Override public void run(){ insert(); System.out.println('thread insert is over'); } } public void insert(){ //do insert...... } }

如果把上面insert方法提出到新的類中,加入事務注解,就能成功的把insert方法加入到事務管理當中

@Service public class ServiceA { @Autowired private ServiceB serviceB; @Transactional public void threadMethod(){ this.insert(); System.out.println('main insert is over'); for(int a=0 ;a<3;a++){ ThreadOperation threadOperation= new ThreadOperation(); Thread innerThread = new Thread(threadOperation); innerThread.start(); } } public class ThreadOperation implements Runnable { public ThreadOperation(){ } @Override public void run(){ serviceB.insert(); System.out.println('thread insert is over'); } } public void insert(){ //do insert...... } } @Service public class ServiceB { @Transactional public void insert(){ //do insert...... } }

另外,使用多線程事務的情況下,進行回滾,比較麻煩。thread的run方法,有個特別之處,它不會拋出異常,但異常會導致線程終止運行。

最麻煩的是,在線程中拋出的異常即使在主線程中使用try…catch也無法截獲這非常糟糕,我們必須要“感知”到異常的發生。比如某個線程在處理重要的事務,當thread異常終止,我必須要收到異常的報告,才能回滾事務。這時可以使用線程的UncaughtExceptionHandler進行異常處理,UncaughtExceptionHandler名字意味著處理未捕獲的異常。更明確的說,它處理未捕獲的運行時異常。

如下代碼線程出要使用①處要拋出異常②處要捕捉異常,并且要拋出RuntimeException③處手動處理回滾邏輯

@Service public class ServiceA { @Autowired private ServiceB serviceB; @Transactional public void threadMethod(){ this.insert(); System.out.println('main insert is over'); for(int a=0 ;a<3;a++){ ThreadOperation threadOperation= new ThreadOperation(); Thread innerThread = new Thread(threadOperation); innerThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { public void uncaughtException(Thread t, Throwable e) { try { serviceB.delete();③ } catch (Exception e1) { e1.printStackTrace(); } } }); innerThread.start(); } } public class ThreadOperation implements Runnable { public ThreadOperation(){ } @Override public void run(){ try { serviceB.insert(); }catch (Exception ex){ ② System.out.println(' Exception in run '); throw new RuntimeException(); } System.out.println('thread insert is over'); } } public void insert(){ //do insert...... } } @Service public class ServiceB { @Transactional public void insert() throws Exception{ ① //do insert...... } @Transactional public void delete() throws Exception{ //do delete...... } }

到此這篇關于詳解Spring中的Transactional屬性的文章就介紹到這了,更多相關Transactional屬性詳解內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
主站蜘蛛池模板: 99国产国人青青视频在线观看 | 黄视频福利 | 精品成人免费一区二区在线播放 | 亚洲精品国产手机 | 日本大学生免费一级一片 | 玖玖爱视频在线观看 | 国产下药迷倒白嫩美女网站 | 国产成人在线视频网站 | 国内精品视频 在线播放 | 一级v片 | 国产91精品高跟丝袜在线 | 亚洲一色 | 绝对真实偷拍盗摄高清在线视频 | 欧美综合偷拍在线另类卡通小说 | 欧美bbwhd极品另类 | 欧美一级成人一区二区三区 | 成人久久18免费软件 | 国产ppp在线视频在线观看 | 97国内精品久久久久久久影视 | 露脸真实国产精品自在| 免费簧网站永久在线播放国产 | 国产免费av片在线观看 | 欧美男女激情 | 日韩欧美一级毛片在线 | 目韩一区二区三区系列片丶 | 黑人破乌克兰美女处 | 不卡的在线视频免费观看 | 亚洲美女在线视频 | 黄色一级片美国 | 欧美 日韩 中字 国产 | 麻豆免费视频网站入口 | 成熟热自由日本语亚洲人 | 在线观看91精品国产不卡免费 | 国产乱人乱精一区二区视频密 | 亚洲国产成人久久77 | 特黄特色大片免费播放 | 成人欧美视频在线看免费 | 91在线视频观看 | 欧美精品黄页免费高清在线 | 色噜噜国产精品视频一区二区 | 一级α片视频 |