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

詳解Spring中REQUIRED事務(wù)的回滾機(jī)制詳解

 更新時(shí)間:2025年09月22日 10:49:00   作者:吟風(fēng)于春  
在Spring的事務(wù)管理中,REQUIRED是最常用也是默認(rèn)的事務(wù)傳播屬性,本文就來詳細(xì)的介紹一下Spring中REQUIRED事務(wù)的回滾機(jī)制,感興趣的可以了解一下

在 Spring 的事務(wù)管理中,REQUIRED 是最常用也是默認(rèn)的事務(wù)傳播屬性。很多開發(fā)者在使用時(shí)會(huì)遇到一個(gè)常見的困惑:為什么內(nèi)部方法拋出的異常即便被外層捕獲了,事務(wù)還是會(huì)整體回滾? 本文將深入剖析 REQUIRED 下的事務(wù)回滾機(jī)制及其背后的原理。

1. REQUIRED 的定義

  • 默認(rèn)傳播屬性。
  • 如果當(dāng)前存在事務(wù):加入當(dāng)前事務(wù)。
  • 如果沒有事務(wù):創(chuàng)建一個(gè)新事務(wù)。

這意味著調(diào)用鏈上的所有方法都運(yùn)行在同一個(gè)物理事務(wù)里,彼此之間沒有隔離。只要其中一個(gè)方法觸發(fā)回滾條件,整個(gè)事務(wù)都會(huì)被撤銷。

2. REQUIRED 下的回滾機(jī)制

2.1 異常觸發(fā)回滾

Spring 默認(rèn)回滾規(guī)則:

  • 運(yùn)行時(shí)異常(RuntimeException)和錯(cuò)誤(Error):觸發(fā)回滾。
  • 受檢異常(CheckedException):不會(huì)觸發(fā)回滾,除非在 @Transactional(rollbackFor = Exception.class) 中顯式指定。

2.2 回滾狀態(tài)傳播

假設(shè)調(diào)用鏈如下:

@Transactional(propagation = Propagation.REQUIRED)
public void outer() {
    try {
        inner();
    } catch (Exception e) {
        // 異常被捕獲
    }
}

@Transactional(propagation = Propagation.REQUIRED)
public void inner() {
    throw new RuntimeException("內(nèi)部錯(cuò)誤");
}

執(zhí)行過程:

  1. outer() 啟動(dòng)時(shí)創(chuàng)建事務(wù)。
  2. inner() 加入同一事務(wù)并拋出異常。
  3. Spring 的事務(wù)攔截器捕獲異常 → 標(biāo)記當(dāng)前事務(wù)為 rollback-only
  4. 即便外層 outer() 捕獲了異常,rollback-only 標(biāo)記不會(huì)自動(dòng)清除。
  5. 最終事務(wù)提交時(shí),Spring 檢查到 rollback-only → 調(diào)用 rollback() 而不是 commit()。

因此,捕獲異常并不能阻止事務(wù)回滾

3. 為什么捕獲異常也會(huì)回滾?

原因在于 Spring 的事務(wù)是基于 事務(wù)狀態(tài)標(biāo)記 而不是你的 try-catch 來決定的:

  • 方法拋出異常 → TransactionInterceptor 判斷是否需要回滾。
  • 如果符合規(guī)則 → status.setRollbackOnly()
  • 外層即便捕獲異常,也只是業(yè)務(wù)層邏輯“消化”了異常,但事務(wù)狀態(tài)已經(jīng)不可提交。

最終由事務(wù)管理器在 commit() 階段檢查 rollback-only 標(biāo)記,決定整體回滾。

4. 如何避免“誤回滾”?

如果確實(shí)需要內(nèi)部異常不影響外部事務(wù),可以考慮以下方式:

4.1 修改回滾規(guī)則

@Transactional(noRollbackFor = RuntimeException.class)
public void inner() {
    throw new RuntimeException("不會(huì)觸發(fā)回滾");
}

但這種方式風(fēng)險(xiǎn)極高,可能提交錯(cuò)誤數(shù)據(jù)。

4.2 手動(dòng)清理事務(wù)狀態(tài)(不推薦)

catch (Exception e) {
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(false);
}

此方式非常危險(xiǎn),通常不建議。

4.3 使用其他傳播屬性(推薦)

  • REQUIRES_NEW:為內(nèi)部方法開啟新事務(wù),失敗只影響內(nèi)部,不影響外部。
  • NESTED:使用保存點(diǎn),內(nèi)部失敗可回滾到保存點(diǎn),外部事務(wù)繼續(xù)。

這兩種方式才是更優(yōu)雅的解決方案。

5. Spring 內(nèi)部執(zhí)行流程

核心邏輯在 TransactionAspectSupport.invokeWithinTransaction()

  1. 獲取或創(chuàng)建事務(wù)。
  2. 執(zhí)行目標(biāo)方法。
  3. 捕獲異常 → 判斷是否需要回滾 → 設(shè)置 rollback-only。
  4. 方法結(jié)束 → 根據(jù)狀態(tài)決定 commit() 還是 rollback()

6. 總結(jié)

  • REQUIRED 下,所有方法共享一個(gè)事務(wù)。
  • 任意方法異常觸發(fā) rollback-only → 整體回滾。
  • 捕獲異常≠事務(wù)安全,Spring 根據(jù)事務(wù)狀態(tài)決定提交還是回滾。
  • 如果需要更細(xì)粒度的控制,應(yīng)使用 REQUIRES_NEWNESTED。

一句話總結(jié):在 Spring 的 REQUIRED 模式下,事務(wù)是一榮俱榮、一損俱損的整體,內(nèi)部異常即便被捕獲也會(huì)讓整個(gè)事務(wù)回滾,真正想做到“局部回滾”需要換傳播屬性來實(shí)現(xiàn)。

到此這篇關(guān)于詳解Spring中REQUIRED事務(wù)的回滾機(jī)制詳解的文章就介紹到這了,更多相關(guān)Spring REQUIRED 事務(wù)回滾內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IDEA中Services欄不顯示的解決方案小結(jié)

    IDEA中Services欄不顯示的解決方案小結(jié)

    正常編譯完一個(gè)SpringBoot或者SringCloud項(xiàng)目之后,Services都會(huì)顯示出你有哪些服務(wù),如果沒有services欄怎么解決呢?下面小編給大家分享IDEA中Services欄不顯示的解決方案小結(jié),感興趣的朋友一起看看吧
    2021-08-08
  • idea數(shù)據(jù)庫驅(qū)動(dòng)下載失敗的問題及解決

    idea數(shù)據(jù)庫驅(qū)動(dòng)下載失敗的問題及解決

    這篇文章主要介紹了idea數(shù)據(jù)庫驅(qū)動(dòng)下載失敗的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • @Slf4j?如何實(shí)現(xiàn)日志輸入到外部文件

    @Slf4j?如何實(shí)現(xiàn)日志輸入到外部文件

    這篇文章主要介紹了@Slf4j?如何實(shí)現(xiàn)日志輸入到外部文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot整合Druid并開啟監(jiān)控過程

    SpringBoot整合Druid并開啟監(jiān)控過程

    Druid高性能數(shù)據(jù)庫連接池與SpringBoot結(jié)合使用,顯著提升數(shù)據(jù)訪問性能,通過內(nèi)置監(jiān)控頁面實(shí)時(shí)查看連接狀態(tài)、SQL執(zhí)行情況等關(guān)鍵信息
    2026-06-06
  • 關(guān)于Spring組成的七大模塊詳解

    關(guān)于Spring組成的七大模塊詳解

    Spring是一個(gè)開源的應(yīng)用框架,用于簡(jiǎn)化企業(yè)級(jí)應(yīng)用開發(fā),它由核心容器、應(yīng)用上下文、面向切面編程、JDBC和DAO模塊、對(duì)象實(shí)體映射、Web模塊和MVC模塊七大模塊組成,這些模塊提供了各種功能,如依賴注入、面向切面編程、ORM支持、Web開發(fā)等,以幫助開發(fā)者更高效地開發(fā)應(yīng)用
    2025-11-11
  • 如何使用新方式編寫Spring MVC接口

    如何使用新方式編寫Spring MVC接口

    這篇文章主要介紹了如何使用新方式編寫Spring MVC接口,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java?ArrayList遍歷foreach與iterator時(shí)remove的區(qū)別

    Java?ArrayList遍歷foreach與iterator時(shí)remove的區(qū)別

    這篇文章主要介紹了Java?ArrayList遍歷foreach與iterator時(shí)remove的區(qū)別,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • SpringCloud整合Netty集群實(shí)現(xiàn)WebSocket的示例代碼

    SpringCloud整合Netty集群實(shí)現(xiàn)WebSocket的示例代碼

    文章主要介紹了SpringCloud整合Netty集群實(shí)現(xiàn)WebSocket的相關(guān)內(nèi)容,包括服務(wù)注冊(cè)和發(fā)現(xiàn)中心的配置,如使用Nacos、CommandLineRunner啟動(dòng)Netty服務(wù)等,還介紹了通過Redis實(shí)現(xiàn)消息發(fā)布訂閱的機(jī)制,需要的朋友可以參考下
    2024-11-11
  • Java實(shí)現(xiàn)線程按序交替執(zhí)行的方法詳解

    Java實(shí)現(xiàn)線程按序交替執(zhí)行的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)線程按序交替執(zhí)行,文中的示例代碼講解詳細(xì),對(duì)我們了解線程有一定幫助,需要的可以參考一下
    2022-10-10
  • java讀取json文件的2種方式例子

    java讀取json文件的2種方式例子

    這篇文章主要給大家介紹了關(guān)于java讀取json文件的2種方式,在開發(fā)過程中有時(shí)會(huì)遇到需要讀取.json文件的需求,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07

最新評(píng)論

崇信县| 长海县| 湖州市| 元阳县| 普陀区| 清水县| 余江县| 平山县| 都江堰市| 梁平县| 清徐县| 天全县| 郑州市| 石渠县| 杭锦旗| 吴旗县| 玛曲县| 苏尼特左旗| 二手房| 浦东新区| 崇阳县| 安多县| 宁河县| 邢台市| 历史| 宣威市| 卓尼县| 安多县| 衡山县| 七台河市| 灌南县| 亚东县| 五大连池市| 赣州市| 积石山| 蒙山县| 锡林郭勒盟| 白城市| 拉萨市| 毕节市| 太康县|