Spring 的核心思想 IOC 與 AOP 在聲明式事務管理中淋漓盡致。相較於笨重的 EJB,Spring 提供輕量級、非侵入式的事務解決方案,無需昂貴應用伺服器即可實現強大的事務控制。本文介紹四種常見的聲明式事務配置方式,從基礎到進階,適應不同規模專案需求。
<!-- 事務管理器 -->
<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>
適用於模組較少的專案,每個 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,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>
優點:大幅減少重複配置,維護容易。
利用攔截器機制,自動為指定 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 名稱。
結合通配符與正則表達式,自動為所有業務層 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 最經典的應用。隨專案規模增長,建議逐步從方式一遷移至方式四,善用命名慣例與自動代理機制,達成「零配置」維護事務邊界,讓開發者專注於業務邏輯。