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

Spring 事務管理全解析:聲明式四種配置方式與編程式實戰對比

     編輯:Java 綜合教學

Spring 事務管理全解析:聲明式四種配置方式與編程式實戰對比

Spring 事務管理是企業級開發核心技能。本文系統整理聲明式事務的四種歷史配置演進(tx 標籤、代理工廠、攔截器、註解驅動)與編程式註解方式,對比優劣適用場景,提供生產環境選型指南。

事務配置三大核心組件

無論何種方式,Spring 事務配置必包含:

  1. DataSource / SessionFactory:資料源或 ORM 會話工廠
  2. TransactionManager:事務管理器實現(DataSourceTransactionManager、HibernateTransactionManager、JtaTransactionManager)
  3. 代理機制:將事務邏輯織入業務方法(AOP 切面、代理 Bean、攔截器、註解)

聲明式事務四種配置演進

方式一:<tx:advice> + <aop:config>(推薦:XML 解耦)

<tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
    <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
    <tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception"/>
    <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
    <tx:method name="*" propagation="REQUIRED" read-only="true"/>
  </tx:attributes>
</tx:advice>

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

優點:業務代碼零侵入、切點表達式靈活、事務屬性集中管理
缺點:XML 配置較繁瑣、需理解 AOP 概念

方式二:TransactionProxyFactoryBean(經典:代理 Bean)

<bean id="txProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
  <property name="transactionManager" ref="transactionManager"/>
  <property name="transactionAttributes">
    <props>
      <prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>
      <prop key="modify*">PROPAGATION_REQUIRED,-Exception</prop>
      <prop key="del*">PROPAGATION_REQUIRED,-Exception</prop>
      <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
    </props>
  </property>
</bean>

<bean id="userDao" parent="txProxy">
  <property name="target">
    <bean class="com.dao.UserDaoImpl">
      <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
  </property>
</bean>

優點:Spring 1.x/2.x 經典寫法、abstract="true" + parent 復用配置
缺點:每個 Bean 需單獨代理、配置膨脹、已被 tx:advice 取代

方式三:TransactionInterceptor + BeanNameAutoProxyCreator(老舊:攔截器)

<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
  <property name="transactionManager" ref="transactionManager"/>
  <property name="transactionAttributes">...</property>
</bean>

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
  <property name="interceptorNames"><list><value>txInterceptor</value></list></property>
  <property name="beanNames"><list><value>*Dao</value></list></property>
</bean>

缺點:配置複雜、靠 Bean 名稱匹配脆弱、不推薦新專案使用

方式四:@Transactional 註解驅動(現代標準:零 XML)

<!-- 啟用註解掃描 -->
<context:annotation-config/>
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional  // 類級:默認事務屬性
public class UserDaoImpl {
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addUser(User user) { ... }
    
    @Transactional(readOnly = true)
    public User findUser(String id) { ... }
}

優點:代碼與配置合一、IDE 支援重構、細粒度控制、Spring Boot 時代標配
缺點:大型專案註解分散、需掃描啟動、僅適用於 public 方法(代理機制限制)

事務傳播行為詳解

傳播類型行為適用場景
REQUIRED支援當前事務,無則新建90% 業務方法默認選擇
SUPPORTS支援當前事務,無則非事務執行查詢方法、只讀操作
MANDATORY必須在事務中執行,無則拋異常強制要求事務上下文的核心操作
REQUIRES_NEW新建事務,掛起當前事務獨立提交:日誌記錄、審計、發送通知
NOT_SUPPORTED非事務執行,掛起當前事務長時間計算、外部 API 調用
NEVER非事務執行,有事務則拋異常嚴格禁止事務的場景
NESTED嵌套事務(保存點),外層回滾內層跟隨批次處理部分回滾、JDBC 3.0+ 支援

編程式事務:TransactionTemplate

@Autowired
private TransactionTemplate txTemplate;

public void complexBusinessLogic() {
    txTemplate.execute(status -> {
        try {
            dao.step1();
            dao.step2();
            return "success";
        } catch (Exception e) {
            status.setRollbackOnly();
            throw new BusinessException("業務失敗", e);
        }
    });
}

適用場景:事務邊界動態決定、需在事務中穿插非事務邏輯、極少數註解無法覆蓋的複雜場景。

生產環境選型建議

專案類型推薦方式理由
Spring Boot 微服務@Transactional + 註解驅動零配置、標準化、生態整合最佳
傳統 Spring XML 專案tx:advice + aop:config業務代碼純淨、集中管理、團隊協作友好
大型單體遷移中混合:核心模塊註解、邊緣模塊 XML漸進式遷移、風險可控
需動態事務控制TransactionTemplate程式化控制事務邊界

關鍵避坑指南

  • @Transactional 僅對 public 方法生效:protected/private/package-private 會被忽略
  • 自我調用失效:類內部方法調用繞過代理,需注入自身或拆分類
  • rollbackFor 默認僅 RuntimeException/Error:檢查型異常需顯式 rollbackFor = Exception.class
  • 資料庫引擎必須支援事務:MyISAM 任何配置無效,強制 InnoDB
  • 連接池 autoCommit=true:交給 Spring 管理,勿手動干預

總結

Spring 事務管理從 XML 代理演進到註解驅動,本質是 AOP 環繞通知 + ThreadLocal 綁定連接。理解四種配置的歷史脈絡與底層原理,能在遷移升級、疑難排查、架構決策中遊刃有餘。現代開發:首選 @Transactional,輔以 tx:advice 處理跨模塊統一策略。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved