首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Spring 事務管理回滾規則深度解析:默認行為、異常分類與自定義策略最佳實踐

     編輯:Java 程式設計入門

核心結論

Spring @Transactional 默認僅對 RuntimeException 及其子類、Error 觸發回滾;Exception(受檢異常)不回滾。

異常體系分類速覽

Throwable
 ├── Error                    // 虛擬機錯誤,不可恢復(OOM、StackOverflow)
 └── Exception
      ├── RuntimeException    // 運行時異常:空指針、越界、類轉換、算術...
      │     ├── NullPointerException
      │     ├── IndexOutOfBoundsException
      │     └── ...
      └── Checked Exception   // 受檢異常:必須 try-catch 或 throws
            ├── IOException
            ├── SQLException
            ├── ClassNotFoundException
            └── ...

默認行為驗證

@Transactional
public void methodA() {
    dao.insert(...);
    throw new RuntimeException("故意拋運行時異常"); // 回滾 ✅
}

@Transactional
public void methodB() throws Exception {
    dao.insert(...);
    throw new IOException("受檢異常"); // 不回滾 ❌
}

自定義回滾規則

1. 指定回滾異常

@Transactional(rollbackFor = Exception.class) // 所有 Exception 及子類回滾
@Transactional(rollbackFor = {IOException.class, MyBizException.class}) // 指定類型

2. 指定不回滾異常

@Transactional(noRollbackFor = RuntimeException.class) // 運行時異常也不回滾(極少用)

3. XML 配置方式

<tx:method name="*" rollback-for="Exception" no-rollback-for="MyIgnoreException"/>

實戰建議:自定義異常體系設計

// 基礎業務異常 → 繼承 RuntimeException,享受默認回滾
public class BizException extends RuntimeException {
    private final ErrorCode code;
    public BizException(ErrorCode code, String msg) { super(msg); this.code = code; }
    public BizException(ErrorCode code, String msg, Throwable cause) { super(msg, cause); this.code = code; }
}

// 特定場景:不想回滾的業務異常(如驗證失敗、幂等重複)
public class NoRollbackBizException extends Exception { // 繼承 Exception
    // ...
}
  • 業務代碼拋 BizException → 自動回滾,無需配置;
  • 特殊場景拋 NoRollbackBizException → 需在 @Transactional 聲明 rollbackFor = Exception.class 才會回滾,否則提交;
  • 統一異常碼 ErrorCode 便於前端處理與日志追蹤。

常見誤區

  1. try-catch 吞掉異常:事務攔截器捕獲不到異常,不會回滾 → catch 後必須重新拋出;
  2. 多線程調用:@Transactional 基於 ThreadLocal 綁定連接,子線程不共享事務上下文 → 需編程式事務或傳遞連接;
  3. 內部方法調用:同類內部調用繞過代理,事務失效 → 注入自身 Bean 或拆分類;
  4. Propagation.NESTED:僅 DataSourceTransactionManager 支援,JTA 不支援。

總結決策表

場景推薦策略
通用業務方法拋 BizException (RuntimeException),無需配置
需回滾受檢異常@Transactional(rollbackFor = Exception.class)
特定異常不回滾自定義 Exception 子類 + noRollbackFor
批量導入部分失敗不回滾整體編程式事務 TransactionTemplate 手動控制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved