最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

踩坑之spring事務(wù),非事務(wù)方法與事務(wù)方法執(zhí)行相互調(diào)用方式

 更新時間:2023年07月26日 09:08:44   作者:西風(fēng)一任秋  
這篇文章主要介紹了踩坑之spring事務(wù),非事務(wù)方法與事務(wù)方法執(zhí)行相互調(diào)用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

踩坑spring事務(wù),非事務(wù)方法與事務(wù)方法執(zhí)行相互調(diào)用

項目環(huán)境 sprinigboot

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

最近在做項目中有個業(yè)務(wù)是每天定時更新xx的數(shù)據(jù),某條記錄更新中數(shù)據(jù)出錯,不影響整體數(shù)據(jù),只需記錄下來并回滾當條記錄所關(guān)聯(lián)的表數(shù)據(jù);

好啊,這個簡單,接到任務(wù)后,樓主我三下五除二就寫完了,由于這個業(yè)務(wù)還是有些麻煩,我就在一個service里拆成了兩個方法去執(zhí)行,一個方法(A)是查詢數(shù)據(jù)與驗證組裝數(shù)據(jù),另外一個方法(B)更新這條數(shù)據(jù)所對應(yīng)的表(執(zhí)行的時候是方法A中調(diào)用方法B);

由于這個數(shù)據(jù)是循環(huán)更新,所以我想的是,一條數(shù)據(jù)更新失敗直接回滾此條數(shù)據(jù)就是,不會影響其他數(shù)據(jù),其他的照常更新,所以我就在方法B上加了事務(wù),方法A沒有加;

以為很完美,自測一下正常,ok通過,再測試一下報錯情況,是否回滾,一測,沒回滾,懵圈兒?

以為代碼寫錯了,改了幾處地方,再測了幾次,均沒回滾.這下是真難受了.

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

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

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

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

spring默認的是PROPAGATION_REQUIRED機制,如果方法A標注了注解@Transactional 是完全沒問題的,執(zhí)行的時候傳播給方法B,因為方法A開啟了事務(wù),線程內(nèi)的connection的屬性autoCommit=false,并且執(zhí)行到方法B時,事務(wù)傳播依然是生效的,得到的還是方法A的connection,autoCommit還是為false,所以事務(wù)生效;反之,如果方法A沒有注解@Transactional 時,是不受事務(wù)管理的,autoCommit=true,那么傳播給方法B的也為true,執(zhí)行完自動提交,即使B標注了@Transactional ;

在一個Service內(nèi)部,事務(wù)方法之間的嵌套調(diào)用,普通方法和事務(wù)方法之間的嵌套調(diào)用,都不會開啟新的事務(wù).

是因為spring采用動態(tài)代理機制來實現(xiàn)事務(wù)控制,而動態(tài)代理最終都是要調(diào)用原始對象的,而原始對象在去調(diào)用方法時,是不會再觸發(fā)代理了!

所以以上就是為什么我在沒有標注事務(wù)注解方法A里去調(diào)用標注有事務(wù)注解方法B而沒有事務(wù)滾回的原因;

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

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

下邊先上下代碼

方法A:無事務(wù)控制

方法B:有事務(wù)控制

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

方法A調(diào)用方法B:

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

下面是解決方案

1.把方法B抽離到另外一個XXService中去,并且在這個Service中注入XXService,使用XXService調(diào)用方法B;

顯然,這種方式一點也不優(yōu)雅,且要產(chǎn)生很多冗余文件,看起來很煩,實際開發(fā)中也幾乎沒人這么做吧?.

反正我不建議采用此方案;

2.通過在方法內(nèi)部獲得當前類代理對象的方式,通過代理對象調(diào)用方法B

上面說了:動態(tài)代理最終都是要調(diào)用原始對象的,而原始對象在去調(diào)用方法時,是不會再觸發(fā)代理了!

所以我們就使用代理對象來調(diào)用,就會觸發(fā)事務(wù);

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

這里提供兩種方式:

  • 1.使用 ApplicationContext 上下文對象獲取該對象;
  • 2.使用 AopContext.currentProxy() 獲取代理對象,但是需要配置exposeProxy=true

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

springboot啟動類加上注解:

@EnableAspectJAutoProxy(exposeProxy = true)

方法內(nèi)部獲取代理對象調(diào)用方法

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

都是事務(wù)這塊兒基礎(chǔ)太差的錯啊~~

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mybatis返回map類型數(shù)據(jù)空值字段不顯示的解決方案

    mybatis返回map類型數(shù)據(jù)空值字段不顯示的解決方案

    這篇文章主要介紹了mybatis返回map類型數(shù)據(jù)空值字段不顯示的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java中常見的XML解析方法與應(yīng)用詳解

    Java中常見的XML解析方法與應(yīng)用詳解

    XML(eXtensible Markup Language)是一種用于存儲和傳輸數(shù)據(jù)的標記語言,被廣泛應(yīng)用于表示和交換獨立于應(yīng)用程序和硬件平臺的結(jié)構(gòu)化信息,下面我們就來看看它的常見解析方法有哪些吧
    2024-01-01
  • java實現(xiàn)二維數(shù)組轉(zhuǎn)置的方法示例

    java實現(xiàn)二維數(shù)組轉(zhuǎn)置的方法示例

    這篇文章主要介紹了java實現(xiàn)二維數(shù)組轉(zhuǎn)置的方法,結(jié)合實例形式詳細分析了java二維數(shù)組轉(zhuǎn)置的原理、實現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • SpringBoot中的yml文件中讀取自定義配置信息及遇到問題小結(jié)

    SpringBoot中的yml文件中讀取自定義配置信息及遇到問題小結(jié)

    這篇文章主要介紹了SpringBoot中的yml文件中讀取自定義配置信息,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Intellij IDEA 最全超實用快捷鍵整理(長期更新)

    Intellij IDEA 最全超實用快捷鍵整理(長期更新)

    這篇文章主要介紹了Intellij IDEA 最全實用快捷鍵整理(長期更新),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • Spring框架學(xué)習(xí)常用注解匯總

    Spring框架學(xué)習(xí)常用注解匯總

    這篇文章主要為大家介紹了Spring框架學(xué)習(xí)中一些經(jīng)常用的注解匯總及示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-10-10
  • Eclipse中引入com.sun.image.codec.jpeg包報錯的完美解決辦法

    Eclipse中引入com.sun.image.codec.jpeg包報錯的完美解決辦法

    Java開發(fā)中對圖片的操作需要引入 com.sun.image.codec.jpeg,但有時引入這個包會報錯,利用下面的操作可以完成解決這個問題
    2018-02-02
  • spring集成okhttp3的步驟詳解

    spring集成okhttp3的步驟詳解

    okhttp是一個封裝URL,比HttpClient更友好易用的工具,下面這篇文章主要給大家介紹了關(guān)于spring集成okhttp3的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2018-04-04
  • Spring Boot配置application.yml及根據(jù)application.yml選擇啟動配置的操作方法

    Spring Boot配置application.yml及根據(jù)application.yml選擇啟動配置的操作

    Spring Boot中可以選擇applicant.properties 作為配置文件,也可以通過在application.yml中進行配置,讓Spring Boot根據(jù)你的選擇進行加載啟動配置文件,本文給大家介紹Spring Boot配置application.yml及根據(jù)application.yml選擇啟動配置的操作方法,感興趣的朋友一起看看吧
    2023-10-10
  • 在SpringMVC框架下實現(xiàn)文件的上傳和下載示例

    在SpringMVC框架下實現(xiàn)文件的上傳和下載示例

    本篇文章主要介紹了在SpringMVC框架下實現(xiàn)文件的上傳和下載示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02

最新評論

曲阜市| 台南县| 文水县| 池州市| 响水县| 鄄城县| 扎赉特旗| 安平县| 观塘区| 莱西市| 瑞安市| 绵阳市| 麦盖提县| 大宁县| 泉州市| 通化县| 浙江省| 义马市| 绿春县| 威信县| 西乌| 安泽县| 讷河市| 南和县| 水城县| 景东| 大庆市| 徐汇区| 静海县| 新乐市| 牟定县| 信阳市| 华亭县| 望城县| 上林县| 威远县| 佛山市| 丰县| 金塔县| 来安县| 嘉峪关市|