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

Spring 事務管理深度解析:編程式與聲明式完整指南

     編輯:Java 相關知識

前言

事務管理是企業級應用核心。Spring 提供統一抽象層,屏蔽底層資源 (JDBC、Hibernate、JPA、JMS) 差異。本文系統剖析 Spring 事務屬性、核心 API、編程式與聲明式四種演進方式,並給出生產環境最佳實踐建議。

一、事務屬性詳解 (TransactionDefinition)

1. 隔離級別

常量語意防止建議
ISOLATION_DEFAULT資料庫預設-多數情況足夠 (通常=READ_COMMITTED)
ISOLATION_READ_UNCOMMITTED可讀未提交無極少用,髒讀風險
ISOLATION_READ_COMMITTED可讀已提交髒讀推薦預設
ISOLATION_REPEATABLE_READ可重複讀髒讀、不可重複讀MySQL InnoDB 預設
ISOLATION_SERIALIZABLE序列化髒讀、不可重複讀、幻讀效能極差,極少用

2. 傳播行為

常量行為適用場景
PROPAGATION_REQUIRED有事務加入,無則新建90% 業務方法預設
PROPAGATION_REQUIRES_NEW強制新事務,掛起現有獨立審計日誌、通知發送
PROPAGATION_SUPPORTS有則加入,無則非事務唯讀查詢
PROPAGATION_NOT_SUPPORTED非事務執行,掛起現有長時間非 DB 操作
PROPAGATION_NEVER非事務,有則拋異常強制禁止事務
PROPAGATION_MANDATORY必須在事務中,無則拋異常核心業務強制事務
PROPAGATION_NESTED巢狀事務 (Savepoint)部分回滾需求 (JDBC 支援)

3. 其他屬性

  • Timeout:秒數,超時自動回滾
  • ReadOnly:true 可啟用資料庫/驅動優化 (如 MySQL 不加鎖)
  • Rollback Rules:預設 RuntimeException 回滾,Checked Exception 提交;可自訂 +Exception (不回滾) / -Exception (回滾)

二、核心 API 三劍客

  1. TransactionDefinition:事務屬性定義 (不可變配置)
  2. PlatformTransactionManager:事務操作執行者
    • DataSourceTransactionManager (JDBC/iBatis/MyBatis)
    • HibernateTransactionManager
    • JpaTransactionManager
    • WebSphereUowTransactionManager (WAS 環境)
    • JtaTransactionManager (分散式/JTA)
  3. TransactionStatus:運行時事務狀態
    • isNewTransaction()、setRollbackOnly()、isRollbackOnly()

三、編程式事務管理

1. 底層 API 風格 (教學用)

public boolean transfer(Long from, Long to, double amt) {
    TransactionStatus status = txManager.getTransaction(txDef);
    try {
        boolean ok = dao.transfer(from, to, amt);
        txManager.commit(status);
        return ok;
    } catch (Exception e) {
        txManager.rollback(status);
        return false;
    }
}

缺點:樣板代碼散落、業務邏輯混雜。

2. TransactionTemplate 風格 (推薦編程式)

public boolean transfer(final Long from, final Long to, final double amt) {
    return transactionTemplate.execute(status -> {
        try {
            return dao.transfer(from, to, amt);
        } catch (Exception e) {
            status.setRollbackOnly();
            return false;
        }
    });
}
  • 回調介面:TransactionCallback<T> / TransactionCallbackWithoutResult
  • 預設規則:RuntimeException/Error → 回滾;Checked Exception → 提交
  • 手動控制:status.setRollbackOnly()

四、聲明式事務管理演進史

1. TransactionInterceptor + ProxyFactoryBean (Spring 1.x)

手工配置攔截器、目標、代理,XML 膨脹嚴重。

2. TransactionProxyFactoryBean (Spring 1.2+ 經典)

合併攔截器與代理配置,仍需每個目標 Bean 一個定義。

3. <tx> + <aop> 命名空間 (Spring 2.x 推薦)

<tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
    <tx:method name="transfer" propagation="REQUIRED"/>
    <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

<aop:config>
  <aop:pointcut id="svcPointcut" expression="execution(* com.example.service.*.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="svcPointcut"/>
</aop:config>

優點:切點表達式批量匹配、XML 精簡、功能最強。

4. @Transactional 註解 (Spring 2.5+ 最簡)

@Transactional(propagation = Propagation.REQUIRED)
public boolean transfer(Long from, Long to, double amt) { ... }

啟用:<tx:annotation-driven transaction-manager="transactionManager"/>

  • 可標註介面/類/方法,方法級覆蓋類級
  • 僅對 public 方法生效 (Spring AOP 基於代理)
  • 建議:不要標註介面 (僅 JDK 動態代理生效,CGLIB 不生效)

五、兩種聲明式方式對比與選型

可混合使用:基礎策略用 <tx:advice>,特例方法加 @Transactional 覆蓋。

六、生產環境避坑指南

  1. 事務管理器 Bean 名稱慣例:命名為 transactionManager,可省略 transaction-manager 屬性
  2. 資料庫連線池:必須配置 (HikariCP),避免頻繁建立連線
  3. @Transactional 失效自查:
    • 方法非 public
    • 同類內部呼叫 (繞過代理)
    • 異常被 catch 未拋出
    • 資料庫引擎不支援事務 (MyISAM)
    • 未掃描到註解 (缺 <tx:annotation-driven> 或 ComponentScan 範圍)
  4. 分散式事務:跨多資料源需 JTA (Atomikos/Bitronix/Seata) 或 Saga/TCC 模式
  5. 只讀事務優化:查詢方法加 readOnly=true,配合連線池 readOnly 狀態

七、總結

Spring 事務管理從底層 API → Template → AOP XML → 註解,每步都在降低樣板代碼、提升可讀性。核心原理始終是 AOP 環繞通知 + ThreadLocal 綁定 Connection/Session。現代專案建議:

  • 基礎架構統一用 <tx:advice> + <aop:config> 定義預設策略
  • 業務代碼極少數特例用 @Transactional 覆蓋
  • 編程式僅用於需精細控制事務邊界的極少數場景 (如批次處理分塊提交)

深入理解 TransactionDefinition 属性語意、傳播行為邊界、隔離級別代價,是排查事務相關 Bug (資料不一致、鎖等待、死鎖) 的前提。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
維度<tx> + AOP@Transactional
批量匹配切點表達式天然支援需逐個標註
可讀性集中配置,業務代碼零污染註解直觀,但分散
彈性極高 (任意切點、多 Advice)中等
學習曲線需懂 AOP 切點語法極低
建議場景大型專案、統一事務策略、複雜切點中小專案、快速開發、團隊熟悉註解