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

Spring 事務管理五大配置方式全解析:從 XML 到全注解

     編輯:Java 相關知識

核心三要素

無論哪種方式,Spring 事務配置永遠由三部分組成:

  1. DataSource:連接池 / SessionFactory
  2. TransactionManager:DataSourceTransactionManager / HibernateTransactionManager / JtaTransactionManager
  3. 代理機制:如何將事務邏輯織入 Bean(五大方式的核心差異)

方式一:每個 Bean 獨立代理(TransactionProxyFactoryBean)

<bean id="userDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target" ref="userDaoTarget"/>
    <property name="proxyInterfaces" value="com.dao.UserDao"/>
    <property name="transactionAttributes">
        <props><prop key="*">PROPAGATION_REQUIRED</prop></props>
    </property>
</bean>

缺點:Bean 多時配置爆炸,維護極其痛苦。

方式二:共享父 Bean 定義(抽象父類)

<bean id="txBase" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
      abstract="true" lazy-init="true">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
        <props><prop key="*">PROPAGATION_REQUIRED</prop></props>
    </property>
</bean>

<bean id="userDao" parent="txBase">
    <property name="target" ref="userDaoTarget"/>
</bean>

改進:減少重複配置,但仍需為每個 Bean 顯式聲明。

方式三:自動代理 + TransactionInterceptor(攔截器模式)

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

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

優點:通配符批量代理,新增 Bean 無需配置。缺點:僅支援 Bean 名稱匹配,不支援切點表達式。

方式四:tx/aop 命名空間(推薦 XML 風格)

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

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

優勢:強大的切點表達式(execution、within、@annotation 等),關注點分離清晰,Spring 2.0+ 標準做法。

方式五:全注解(@Transactional + @EnableTransactionManagement)

XML 啟用

<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="com.service"/>

JavaConfig 啟用(Spring 3.1+)

@Configuration
@EnableTransactionManagement
@ComponentScan("com.service")
public class TxConfig {
    @Bean
    public DataSource dataSource() { ... }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

業務代碼

@Service
@Transactional // 類級別:所有 public 方法開啟事務
public class UserService {
    @Autowired UserDao userDao;

    @Transactional(readOnly = true) // 方法級別覆蓋:只讀優化
    public User getById(Long id) { return userDao.findById(id); }

    @Transactional(rollbackFor = Exception.class) // 指定回滾異常
    public void register(User user) { userDao.save(user); }
}

五大方式對比總結

方式配置量靈活度可讀性推薦場景
1. 獨立代理極大低差極少 Bean 的微型項目
2. 父 Bean 共享大中中Spring 1.x 遺留項目維護
3. 自動代理攔截器中中(僅名稱匹配)中命名規範嚴格、不想引入 AOP 命名空間
4. tx/aop 命名空間小高(切點表達式)好傳統 XML 專案、需精細控制切點
5. 全注解極小最高(方法級覆蓋)最好現代 Spring 專案首選

遷移建議

  1. 新專案:直接用 方式五(全注解 + JavaConfig)
  2. 老 XML 專案:逐步遷移至 方式四(tx/aop 命名空間),再引入注解
  3. 避免混用多種方式導致事務邊界混亂、重複代理

本質上,所有方式最終都生成 TransactionInterceptor 織入目標 Bean。選擇哪種只是「配置風格」差異,運行時行為一致。

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