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

Spring 聲明式事務管理的四種配置方式詳解

     編輯:Java 相關知識

前言

Spring 的核心思想 IOC 與 AOP 在聲明式事務管理中淋漓盡致。相較於笨重的 EJB,Spring 提供輕量級、非侵入式的事務解決方案,無需昂貴應用伺服器即可實現強大的事務控制。本文介紹四種常見的聲明式事務配置方式,從基礎到進階,適應不同規模專案需求。

基礎 Bean 定義

<!-- 事務管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>

<!-- 業務邏輯 Bean -->
<bean id="fundService" class="com.jack.fund.service.serviceimpl.FundService">
    <property name="operdao"><ref bean="operatorDAO"/></property>
    <property name="producedao"><ref bean="fundProduceDAO"/></property>
    <!-- 其他 DAO 注入 -->
</bean>

方式一:TransactionProxyFactoryBean 逐一定義

適用於模組較少的專案,每個 Service 獨立配置一個 Proxy。

<bean id="fundServiceDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="proxyTargetClass"><value>false</value></property>
    <property name="proxyInterfaces"><value>com.jack.fund.service.IFundService</value></property>
    <property name="target"><ref bean="fundService"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
            <prop key="add*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>

缺點:模組多時配置重複冗長。

方式二:父子 Bean 繼承簡化配置

適用於模組較多,將共同事務屬性抽取至父 Bean。

<!-- 父 Bean,abstract=true 不直接實例化 -->
<bean id="transactionBase" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
      lazy-init="true" abstract="true">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
            <prop key="add*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>

<!-- 子 Bean 僅指定 target -->
<bean id="fundServiceDAOProxy" parent="transactionBase">
    <property name="target"><ref bean="fundService"/></property>
</bean>

優點:大幅減少重複配置,維護容易。

方式三:BeanNameAutoProxyCreator 自動建立 Proxy

利用攔截器機制,自動為指定 Bean 建立事務 Proxy。

<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
            <prop key="add*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>

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

優點:無需為每個 Service 定義 Proxy Bean,僅列出 Bean 名稱。

方式四:自動代理所有 *Service Bean(大型專案首選)

結合通配符與正則表達式,自動為所有業務層 Bean 套用事務。

<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="delete*">PROPAGATION_REQUIRED</prop>
            <prop key="add*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>

<bean id="autoproxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="beanNames">
        <list><value>*Service</value></list> <!-- 所有以 Service 結尾的 Bean -->
    </property>
    <property name="interceptorNames">
        <list><value>transactionInterceptor</value></list>
    </property>
</bean>

進階用法:結合 DefaultAdvisorAutoProxyCreator + RegexpMethodPointcutAdvisor 實現更精細的切點控制。

四種方式選擇指南

方式適用場景維護性靈活度
1. 逐一定義模組極少(<5)低高(可逐一定義不同屬性)
2. 父子繼承模組中等(5~20),事務屬性相似中中
3. BeanNameAutoProxyCreator模組較多,需明確列出 Bean 名稱高中
4. 通配符自動代理大型專案(幾十上百模組),命名規範最高高(結合 Advisor 可極致客製)

結語

聲明式事務是 Spring AOP 最經典的應用。隨專案規模增長,建議逐步從方式一遷移至方式四,善用命名慣例與自動代理機制,達成「零配置」維護事務邊界,讓開發者專注於業務邏輯。

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