日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring 事务方法与非事务方法相互调用 @Transactional 注解失效不回滚?

發布時間:2025/3/12 javascript 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring 事务方法与非事务方法相互调用 @Transactional 注解失效不回滚? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫這篇文章的初衷呢就是最近遇到了一個Spring事務的大坑。與其說是坑,還不如說是自己事務這塊兒太薄弱導致的(自嘲下)。

項目環境 Spring Boot

下面開始問題描述,發生的過程有點長,想直接看方案的直接跳過哦~!

最近在做項目中有個業務是每天定時更新xx的數據,某條記錄更新中數據出錯,不影響整體數據,只需記錄下來并回滾當條記錄所關聯的表數據;好啊!

這個簡單,接到任務后,樓主我三下五除二就寫完了,由于這個業務還是有些麻煩,我就在一個service里拆成了兩個方法去執行,一個方法(A) 是查詢數據與驗證組裝數據。

推薦后臺管理開源框架,基于 Spring Boot、Spring Security、JWT 后端框架,Vue & Element 前端框架的前后端分離的用戶權限管理系統,代碼易讀易懂、界面簡潔美觀。其核心技術采用 Spring、MyBatis、Shiro 沒有任何其它過度依賴包,下載即可運行使用。

另外一個方法(B)更新這條數據所對應的表(執行的時候是方法A中調用方法B);由于這個數據是循環更新,所以我想的是,一條數據更新失敗直接回滾此條數據就是,不會影響其他數據,其他的照常更新,所以我就在方法B上加了事務,方法A沒有加;以為很完美,自測一下正常。

ok通過,再測試一下報錯情況,是否回滾,一測沒回滾,懵圈兒?以為代碼寫錯了,改了幾處地方,再測了幾次,均沒回滾。這下是真難受了。

好啦,寫到這里相信各位看官心里肯定在嘲諷老弟了,spring的傳播機制都沒搞明白(難受)。

下面開始一步步分析解決問題:

首先我們來看下spring事務的傳播機制及原因分析;

PROPAGATION_REQUIRED – 支持當前事務,如果當前沒有事務,就新建一個事務。
這是最常見的選擇。
PROPAGATION_SUPPORTS – 支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY – 支持當前事務,如果當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW – 新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED – 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER – 以非事務方式執行,如果當前存在事務,則拋出異常。
PROPAGATION_NESTED – 如果當前存在事務,則在嵌套事務內執行。
如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。

spring默認的是PROPAGATION_REQUIRED機制,如果方法A標注了注解@Transactional** 是完全沒問題的,執行的時候傳播給方法B**,因為方法A開啟了事務,線程內的connection的屬性autoCommit=false,并且執行到方法B時。事務傳播依然是生效的,得到的還是方法A**的connection,autoCommit還是為false,所以事務生效;

反之,如果方法A沒有注解**@Transactional** 時是不受事務管理的,autoCommit=true,那么傳播給方法B的也為true,執行完自動提交,即使B標注了**@Transactional ;**

在一個Service內部,事務方法之間的嵌套調用,普通方法和事務方法之間的嵌套調用,都不會開啟新的事務。是因為spring采用動態代理機制來實現事務控制,而動態代理最終都是要調用原始對象的,而原始對象在去調用方法時,是不會再觸發代理了!

所以以上就是為什么我在沒有標注事務注解方法A里去調用標注有事務注解方法B而沒有事務滾回的原因。

看到這里,有的看官可能在想你在方法A上標個注解不就完了嗎?為什么非要標注在方法B上?

由于我這里是循環更新數據,調用一次方法B就更新一次數據,涉及到幾張表,需要執行幾條update sql,一條數據更新失敗不影響所有數據,所以說一條數據更新執行完畢后就提交一次事務,如果標注在方法A上,要所有的都執行完畢了才提交事務,這樣子是有問題滴。

下邊先上下代碼:

方法A:無事務控制

方法B:有事務控制

方法B處理失敗手動拋出異常觸發回滾:

方法A調用方法B:

從上圖可以看到,如果方法B中User更新出錯后需要回滾RedPacket數據,所以User更新失敗就拋出了繼承自RuntimeException的自定義異常,并且在調用方把這個異常catch到重新拋出,觸發事務回滾,但是并沒有執行;

解決方案

1、把方法B抽離到另外一個XXService中去,并且在這個Service中注入XXService,使用XXService調用方法B。

顯然,這種方式一點也不優雅,且要產生很多冗余文件,看起來很煩,實際開發中也幾乎沒人這么做吧?反正我不建議采用此方案;

2、通過在方法內部獲得當前類代理對象的方式,通過代理對象調用方法B

上面說了:動態代理最終都是要調用原始對象的,而原始對象在去調用方法時,是不會再觸發代理了!

所以我們就使用代理對象來調用,就會觸發事務;

綜上解決方案,我覺得第二種方式簡直方便到炸,那怎么獲取代理對象呢?這里提供兩種方式:

1、使用 ApplicationContext 上下文對象獲取該對象;

2、使用 AopContext.currentProxy() 獲取代理對象,但是需要配置exposeProxy=true

我這里使用的是第二種解決方案,具體操作如下:

springboot啟動類加上注解:@EnableAspectJAutoProxy(exposeProxy = true)

方法內部獲取代理對象調用方法

完了后再測試,數據順利回滾,至此,問題得到解決!

都是事務這塊兒基礎太差的錯啊~~希望各位遇到這種問題的兄弟些都好好的去研究研究spring這塊兒,好了不說了,我也該去深造了!

總結

以上是生活随笔為你收集整理的Spring 事务方法与非事务方法相互调用 @Transactional 注解失效不回滚?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲乱码一区二区 | 日本在线高清 | 免费看又黄又无码的网站 | 91视频免费看 | 欧美日a| 精品国产久 | 在线观视频免费观看 | 在线观看的黄色网址 | 少妇xxxx69 | 亚洲图片中文字幕 | 91插插插插插插插 | 国产亚洲精品美女 | 抱着老师的嫩臀猛然挺进视频 | 亚洲欧美自拍另类 | 成人在线观看黄色 | 蜜桃久久精品成人无码av | 波多野结衣一区二区三区中文字幕 | 免费亚洲视频 | 欧美8888 | 狠狠干狠狠干狠狠干 | 午夜性色 | 免费在线观看a视频 | 色666| 亚洲欧美一区二区三区久久 | 欧美日韩观看 | 午夜香蕉网 | 女生裸体无遮挡 | 美女张开腿让男人桶爽 | 国产又色又爽又黄的 | 久久av一区二区三区亚洲 | 亚洲啪 | 国产福利短视频 | 天天想你在线观看完整版电影高清 | 182在线视频| 老司机深夜免费福利 | 男女在线观看 | 四虎网站在线观看 | 我们好看的2018视频在线观看 | 91香蕉黄 | 另类激情综合 | 国产福利视频在线 | 青青草在线播放 | 久草免费福利视频 | 成人18视频| 国产精品白嫩极品美女视频 | 日本黄色片. | 亚洲区视频 | 少妇又色又紧又大爽又刺激 | 日韩在线一区二区 | 99热精品免费 | 欧美h视频在线观看 | 日本不卡在线观看 | 91欧美日韩麻豆精品 | 色婷婷精品国产一区二区三区 | 操操干干 | 今天最新中文字幕mv高清 | 樱花视频在线观看 | 久久精品综合网 | 日本高清视频免费观看 | 国产主播一区二区 | 欧美日韩在线播放视频 | 99久久婷婷 | 天堂资源站 | 亚洲欧美日韩精品在线 | 欧美人与性动交ccoo | 激情五月色综合国产精品 | 亚洲成人www | 亚洲天堂av线 | 欧美三级大片 | 日韩三级免费观看 | 亚洲色图视频在线观看 | 亚洲v在线观看 | 久久精品免费 | 久久久久久一区二区 | 久久人人视频 | 一道本久久 | 免费观看一级一片 | 国产精品三区在线观看 | 风间由美在线视频 | 98超碰在线| 免费观看久久 | 精品小视频在线观看 | 91av在线视频播放 | 亚洲欧洲精品一区二区三区 | 91直接进入| 中文字幕人妻无码系列第三区 | 蝌蚪久久 | 亚洲福利视频网站 | 亚洲啪| 黄色片网站在线播放 | 亚洲乱亚洲乱妇 | 国产肥熟| 国产一区二区黑人欧美xxxx | 欧美啪啪一区 | 久久久久久久久久av | 五月婷婷激情综合 | 日本久久久久久久久 | 亚洲乱仑| 色婷婷一区二区三区四区 |