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

詳解Spring中REQUIRED事務的回滾機制詳解

 更新時間:2025年09月22日 10:49:00   作者:吟風于春  
在Spring的事務管理中,REQUIRED是最常用也是默認的事務傳播屬性,本文就來詳細的介紹一下Spring中REQUIRED事務的回滾機制,感興趣的可以了解一下

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

1. REQUIRED 的定義

  • 默認傳播屬性
  • 如果當前存在事務:加入當前事務。
  • 如果沒有事務:創(chuàng)建一個新事務。

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

2. REQUIRED 下的回滾機制

2.1 異常觸發(fā)回滾

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

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

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

假設調(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)部錯誤");
}

執(zhí)行過程:

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

因此,捕獲異常并不能阻止事務回滾。

3. 為什么捕獲異常也會回滾?

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

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

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

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

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

4.1 修改回滾規(guī)則

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

但這種方式風險極高,可能提交錯誤數(shù)據(jù)。

4.2 手動清理事務狀態(tài)(不推薦)

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

此方式非常危險,通常不建議。

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

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

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

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

核心邏輯在 TransactionAspectSupport.invokeWithinTransaction()

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

6. 總結(jié)

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論

泸溪县| 隆德县| 仁怀市| 宜丰县| 邛崃市| 平潭县| 德格县| 嘉荫县| 泗洪县| 隆昌县| 井陉县| 齐齐哈尔市| 濮阳县| 涞源县| 宿迁市| 淮滨县| 鄄城县| 雷州市| 汉川市| 隆回县| 沙田区| 桦南县| 屏边| 淮北市| 齐河县| 平果县| 唐海县| 运城市| 横山县| 台湾省| 石棉县| 台江县| 修武县| 延安市| 邛崃市| 石林| 庆云县| 永和县| 鱼台县| 兰州市| 互助|