您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“如何解決SpringBoot中使用@Transactional注解遇到的問(wèn)題”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“如何解決SpringBoot中使用@Transactional注解遇到的問(wèn)題”這篇文章吧。
1、不建議在接口上添加@Transactional注解,一般在service類(lèi)標(biāo)簽上添加@Transactional即可
2、@Transactional注解只能應(yīng)用到public可見(jiàn)度的方法上。如果應(yīng)用到protected、private或者package可見(jiàn)度的方法上時(shí),不會(huì)報(bào)錯(cuò),但事務(wù)也不會(huì)起作用
3、默認(rèn)情況下,spring會(huì)對(duì)uncheck異常進(jìn)行事務(wù)回滾的;如果是checked異常則不會(huì)回滾,可添加注解 @Transactional(rollbackFor=Exception.class) 是的checked異?;貪L。
uncheck異常:java里面將派生于Error或者RuntimeException(比如空指針,1/0)的異常
checked異常:其他繼承自java.lang.Exception得異常統(tǒng)稱(chēng)為Checked Exception,如IOException、TimeoutException等 4、數(shù)據(jù)庫(kù)引擎需要支持事務(wù)管理,如果是mysql,注意表要使用事務(wù)的引擎,比如innodb,如果是myisam,事務(wù)不會(huì)起作用的
5、同一類(lèi)中methodA()方法沒(méi)有@Transactional 注解,在其內(nèi)部調(diào)用有@Transactional 注解的方法,有@Transactional 注解的方法methodB()的事務(wù)被忽略,不會(huì)開(kāi)啟新的事務(wù),也不會(huì)發(fā)生回滾。例如:
@Service public class TransactionService { public void methodA(){ this.methodB(); } @Transactional public void methodB(){ } }
Spring采用動(dòng)態(tài)代理(AOP)實(shí)現(xiàn)對(duì)bean的管理和切片,它為我們的每個(gè)class生成一個(gè)代理對(duì)象。只有在代理對(duì)象之間進(jìn)行調(diào)用時(shí),可以觸發(fā)切面邏輯。在 Spring 的 AOP 代理下,只有目標(biāo)方法由外部調(diào)用,目標(biāo)方法才由 Spring 生成的代理對(duì)象來(lái)管理。
Spring的事務(wù)管理是通過(guò)AOP實(shí)現(xiàn)的,其AOP的實(shí)現(xiàn)對(duì)于非final類(lèi)是通過(guò)cglib這種方式,即生成當(dāng)前類(lèi)的一個(gè)子類(lèi)作為代理類(lèi),然后在調(diào)用其下的方法時(shí),會(huì)判斷這個(gè)方法有沒(méi)有@Transactional注解,如果有的話(huà),則會(huì)開(kāi)啟一個(gè)新的事務(wù),并通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)事務(wù)管理(攔截方法調(diào)用,執(zhí)行事務(wù)等切面)。
當(dāng)methodA()中調(diào)用methodB()時(shí),并不是使用的代理對(duì)象,而是普通的javabean,從而導(dǎo)致this.methodB()時(shí)也不是代碼對(duì)象,從而導(dǎo)致@Transactional失敗,即發(fā)現(xiàn)methodA()上并沒(méi)有@Transactional注解,所以整個(gè)AOP代理過(guò)程(事務(wù)管理)不會(huì)發(fā)生。
1、把這兩個(gè)方法分開(kāi)到不同的類(lèi)中;
2、把注解@Transactional加到類(lèi)名上面去;
3、把注解@Transactional加到methodA()方法上,methodB()不添加注解,在調(diào)用methodB()時(shí)兩個(gè)方法的事務(wù)都會(huì)生效,因?yàn)閙ethodA()默認(rèn)的事務(wù)傳播屬性為PROPAGATION_REQUIRED,此時(shí)methodB()會(huì)加入到methodA()中
@Service public class TransactionService { @Transactional public void methodA(){ this.methodB(); } public void methodB(){ } }
4、獲取本對(duì)象的代理對(duì)象,再進(jìn)行調(diào)用。具體操作如:
Spring-content.xml上下文中,增加配置:<aop:aspectj-autoproxy expose-proxy="true"/>
在TransactionService 中,用(transactionService )(AopContext.currentProxy()),獲取到TransactionService 的代理類(lèi),再調(diào)用事務(wù)方法,強(qiáng)行經(jīng)過(guò)代理類(lèi),激活事務(wù)切面。
1、在方法中捕獲了異常,那么該方法事務(wù)不會(huì)回滾。
本類(lèi)中A方法(有事務(wù)注解)調(diào)用其他類(lèi)中B方法(有事務(wù)注解,該類(lèi)在容器中),B方法中捕獲了異常,事務(wù)失效不可以回滾,在B方法中的catch里進(jìn)行異常拋出則可以正常回滾。
本類(lèi)中A方法(有事務(wù)注解)調(diào)用其他類(lèi)中B方法(有事務(wù)注解,該類(lèi)在容器中),A方法中捕獲了異常,spring事務(wù)機(jī)制檢測(cè)到異常,進(jìn)行回滾。
所以最好在業(yè)務(wù)層catch中拋出異常讓控制層捕獲。
2、spring中事務(wù)是代理模式,在該類(lèi)中A方法調(diào)用本類(lèi)中B方法,A方法上沒(méi)有事務(wù)注解,B方法上有事務(wù)注解,則B方法中出現(xiàn)異常,B方法事務(wù)不會(huì)回滾,A方法沒(méi)有事務(wù)注解也不會(huì)回滾。
3、A方法如果有事務(wù)注解,調(diào)用了本類(lèi)B方法,B方法出現(xiàn)異常也整體可回滾。
4、本類(lèi)中A方法調(diào)用其他類(lèi)中B方法(有事務(wù)注解,該類(lèi)在容器中),B方法發(fā)生異常,可以回滾
以上是“如何解決SpringBoot中使用@Transactional注解遇到的問(wèn)題”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。