解決SpringBoot中使用@Transactional注解遇到的問題
使用@Transactional注解遇到的問題
1、不建議在接口上添加@Transactional注解
一般在service類標(biāo)簽上添加@Transactional即可
2、@Transactional注解
只能應(yīng)用到public可見度的方法上。如果應(yīng)用到protected、private或者package可見度的方法上時,不會報錯,但事務(wù)也不會起作用
3、默認情況下
spring會對uncheck異常進行事務(wù)回滾的;如果是checked異常則不會回滾,可添加注解 @Transactional(rollbackFor=Exception.class) 是的checked異?;貪L。
- uncheck異常:java里面將派生于Error或者RuntimeException(比如空指針,1/0)的異常
- checked異常:其他繼承自java.lang.Exception得異常統(tǒng)稱為Checked Exception,如IOException、TimeoutException等
4、數(shù)據(jù)庫引擎需要支持事務(wù)管理
如果是mysql,注意表要使用事務(wù)的引擎,比如innodb,如果是myisam,事務(wù)不會起作用的
5、同一類中methodA()方法
沒有@Transactional 注解,在其內(nèi)部調(diào)用有@Transactional 注解的方法,有@Transactional 注解的方法methodB()的事務(wù)被忽略,不會開啟新的事務(wù),也不會發(fā)生回滾。例如:
@Service public class TransactionService { public void methodA(){ this.methodB(); } @Transactional public void methodB(){ } }
原因:Spring采用動態(tài)代理(AOP)實現(xiàn)對bean的管理和切片,它為我們的每個class生成一個代理對象。只有在代理對象之間進行調(diào)用時,可以觸發(fā)切面邏輯。在 Spring 的 AOP 代理下,只有目標(biāo)方法由外部調(diào)用,目標(biāo)方法才由 Spring 生成的代理對象來管理。
詳解:Spring的事務(wù)管理是通過AOP實現(xiàn)的,其AOP的實現(xiàn)對于非final類是通過cglib這種方式,即生成當(dāng)前類的一個子類作為代理類,然后在調(diào)用其下的方法時,會判斷這個方法有沒有@Transactional注解,如果有的話,則會開啟一個新的事務(wù),并通過動態(tài)代理實現(xiàn)事務(wù)管理(攔截方法調(diào)用,執(zhí)行事務(wù)等切面)。
當(dāng)methodA()中調(diào)用methodB()時,并不是使用的代理對象,而是普通的javabean,從而導(dǎo)致this.methodB()時也不是代碼對象,從而導(dǎo)致@Transactional失敗,即發(fā)現(xiàn)methodA()上并沒有@Transactional注解,所以整個AOP代理過程(事務(wù)管理)不會發(fā)生。
解決辦法:
1、把這兩個方法分開到不同的類中;
2、把注解@Transactional加到類名上面去;
3、把注解@Transactional加到methodA()方法上,methodB()不添加注解,在調(diào)用methodB()時兩個方法的事務(wù)都會生效,因為methodA()默認的事務(wù)傳播屬性為PROPAGATION_REQUIRED,此時methodB()會加入到methodA()中
@Service public class TransactionService { @Transactional public void methodA(){ this.methodB(); } public void methodB(){ } }
4、獲取本對象的代理對象,再進行調(diào)用。具體操作如:
- Spring-content.xml上下文中,增加配置:<aop:aspectj-autoproxy expose-proxy="true"/>
- 在TransactionService 中,用(transactionService )(AopContext.currentProxy()),獲取到TransactionService 的代理類,再調(diào)用事務(wù)方法,強行經(jīng)過代理類,激活事務(wù)切面。
springboot 注解transactional失效
1、在方法中捕獲了異常
那么該方法事務(wù)不會回滾。本類中A方法(有事務(wù)注解)調(diào)用其他類中B方法(有事務(wù)注解,該類在容器中),B方法中捕獲了異常,事務(wù)失效不可以回滾,在B方法中的catch里進行異常拋出則可以正?;貪L。
本類中A方法(有事務(wù)注解)調(diào)用其他類中B方法(有事務(wù)注解,該類在容器中),A方法中捕獲了異常,spring事務(wù)機制檢測到異常,進行回滾。
所以最好在業(yè)務(wù)層catch中拋出異常讓控制層捕獲。
2、spring中事務(wù)是代理模式
在該類中A方法調(diào)用本類中B方法,A方法上沒有事務(wù)注解,B方法上有事務(wù)注解,則B方法中出現(xiàn)異常,B方法事務(wù)不會回滾,A方法沒有事務(wù)注解也不會回滾。
3、A方法如果有事務(wù)注解
調(diào)用了本類B方法,B方法出現(xiàn)異常也整體可回滾。
4、本類中A方法調(diào)用
其他類中B方法(有事務(wù)注解,該類在容器中),B方法發(fā)生異常,可以回滾。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
IntelliJ IDEA本地代碼提交到github網(wǎng)站不顯示與本地不同步問題的解決辦法
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA本地代碼提交到github網(wǎng)站不顯示與本地不同步問題的解決辦法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10深入探究一下Java中不同的線程間數(shù)據(jù)通信方式
這篇文章主要來和大家一起深入探究一下Java中不同的線程間數(shù)據(jù)通信方式,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以參考一下2023-04-04spring mvc4的日期/數(shù)字格式化、枚舉轉(zhuǎn)換示例
本篇文章主要介紹了spring mvc4的日期/數(shù)字格式化、枚舉轉(zhuǎn)換示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-01-01Java實現(xiàn)批量查找與替換Excel文本的思路詳解
在 Java 中,可以通過find和replace的方法來查找和替換單元格的數(shù)據(jù),下面小編將以Excel文件為例為大家介紹如何實現(xiàn)Excel文件內(nèi)容的批量替換,感興趣的朋友跟隨小編一起看看吧2023-10-10