從Spring源碼解析事務(wù)失效的原因
一、前言
1.Bean是否是代理對(duì)象
2.入口函數(shù)是否是public的
3.數(shù)據(jù)庫(kù)是否支持事務(wù)(Mysql的Mvlsam不支持事務(wù)),行鎖才支持事務(wù)
4.切點(diǎn)是否配置正確
5.內(nèi)部方法間調(diào)用導(dǎo)致事務(wù)失效
因?yàn)閠his不是代理對(duì)象,可以配置 expose-proxy="true",就可以通過AopContext.currentProxy()獲取到當(dāng)前類的代理對(duì)象。
<! -- expose-proxy="true”類內(nèi)部可以獲取到當(dāng)前類的代理對(duì)象--><aop: aspectj-autoproxy expose-proxy="true" /> @Enab1eAspect3AutoProxy(exposeProxy = true)
也可以注入當(dāng)前bean
6.異常類型是否配置正確
默認(rèn)只支持RuntimeException和Error,不支持檢查異常
想要支持檢查異常需要配置rollbackFor
@Transactional(rollbackFor = Exception.class)
7.異常被catch住了
代碼中手動(dòng)catch了異常,然后又未拋出來,此時(shí)事務(wù)就不生效了。
二、方法不是 public 的
以下來自Spring官方文檔

大概意思就是 @Transactional 只能用于 public 的方法上,否則事務(wù)不會(huì)失效,如果要用在非 public 方法上,可以開啟 AspectJ 代理模式。

TransactionInterceptor#invoke

TransactionAspectSupport#invokeWithinTransaction

AbstractFallbackTransactionAttributeSource#getTransactionAttribute

AbstractFallbackTransactionAttributeSource#computeTransactionAttribute

allowPublicMethodsOnly方法由子類AnnotationTransactionAttributeSource實(shí)現(xiàn),該子類方法中默認(rèn)是true,所以當(dāng)你加了事務(wù)注解的方法不是public時(shí),該方法直接返回null
以上只說明 在spring的事務(wù)管理中存在這樣一個(gè) public的判斷,至于后邊為啥由于這個(gè)判斷導(dǎo)致沒有織入事務(wù),并沒有說明;
public導(dǎo)致失效原因
三、內(nèi)部方法間調(diào)用導(dǎo)致事務(wù)失效

因?yàn)閟pring聲明式事務(wù)是基于AOP實(shí)現(xiàn)的,是使用動(dòng)態(tài)代理來達(dá)到事務(wù)管理的目的,當(dāng)前類調(diào)用的方法上面加@Transactional 這個(gè)是沒有任何作用的,因?yàn)檎{(diào)用這個(gè)方法的是this,沒有經(jīng)過 Spring 的代理類。
解決方案一:
再聲明一個(gè)service,自己注入自己,將內(nèi)部調(diào)用改為外部調(diào)用

解決方案二:







解決方案三:
使用編程式事務(wù)

四、異常類型是否配置正確
拋出RuntimeException異常,事務(wù)生效
拋出Exception異常,事務(wù)不生效




我們看下TransactionInterceptor類
TransactionInterceptor#invoke

TransactionAspectSupport#invokeWithinTransaction

TransactionAspectSupport#completeTransactionAfterThrowing



配置了這個(gè),Exception異常的事務(wù),就會(huì)生效

五、異常被catch住
代碼中手動(dòng)catch了異常,然后又未拋出來,此時(shí)事務(wù)就不生效了。
解決方法:要么不catch需要回滾的異常,要么catch之后再拋出,要么手動(dòng)回滾

解決方案一:
catch之后往外拋異常

解決方案二:
catch之后,設(shè)置手動(dòng)回滾

到此這篇關(guān)于從Spring源碼解析事務(wù)失效的原因的文章就介紹到這了,更多相關(guān)Spring事務(wù)失效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Maven Plugins報(bào)錯(cuò)的解決方法
本文主要介紹了Maven Plugins報(bào)錯(cuò)的解決方法,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02
IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解
查看JAVA字節(jié)碼有兩種方式一種是使用 jdk命令 javap,還有一種就是 使用 插件了,今天給大家分享IDEA中使用jclasslib插件可視化方式查看類字節(jié)碼的過程詳解,感興趣的朋友跟隨小編一起看看吧2021-05-05
結(jié)合mybatis-plus實(shí)現(xiàn)簡(jiǎn)單不需要寫sql的多表查詢
這篇文章主要給大家介紹了關(guān)于結(jié)合mybatis-plus實(shí)現(xiàn)簡(jiǎn)單不需要寫sql的多表查詢的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用mybatis-plus具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
springboot啟動(dòng)報(bào)錯(cuò):application?startup?failed問題
這篇文章主要介紹了springboot啟動(dòng)報(bào)錯(cuò):application?startup?failed問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Java使用ProcessBuilder?API優(yōu)化流程
Java?的?Process?API?為開發(fā)者提供了執(zhí)行操作系統(tǒng)命令的強(qiáng)大功能,這篇文章將詳細(xì)介紹如何使用?ProcessBuilder?API?來方便的操作系統(tǒng)命令,需要的可以收藏一下2023-06-06
SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)
這篇文章主要介紹了SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Java RandomAccessFile 指定位置實(shí)現(xiàn)文件讀取與寫入
這篇文章主要介紹了Java RandomAccessFile 指定位置實(shí)現(xiàn)文件讀取與寫入的相關(guān)資料,需要的朋友可以參考下2017-01-01
jdk中動(dòng)態(tài)代理異常處理分析:UndeclaredThrowableException
最近在工作中遇到了報(bào)UndeclaredThrowableException的錯(cuò)誤,通過查找相關(guān)的資料,終于解決了,所以這篇文章主要給大家介紹了關(guān)于jdk中動(dòng)態(tài)代理異常處理分析:UndeclaredThrowableException的相關(guān)資料,需要的朋友可以參考下2018-04-04

