聲明式的事務劃分
我們可以使用Spring的AOP TransactionInterceptor來替換事務劃分的手工代碼, 這需要在application context中定義interceptor。 這個方案使得你可以把業務對象從每個業務方法中重復的事務劃分代碼中解放出來。 此外,像傳播行為和隔離級別等事務概念能夠在配置文件中改變,而不會影響業務對象的實現。
<beans> ... <bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="mySessionFactory"/> </property> </bean> <bean id="myTransactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager"> <ref bean="myTransactionManager"/> </property> <property name="transactionAttributeSource"> <value> product.ProductService.increasePrice*=PROPAGATION_REQUIRED product.ProductService.someOtherBusinessMethod=PROPAGATION_MANDATORY </value> </property> </bean> <bean id="myProductServiceTarget" class="product.ProductServiceImpl"> <property name="productDao"> <ref bean="myProductDao"/> </property> </bean> <bean id="myProductService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>product.ProductService</value> </property> <property name="interceptorNames"> <list> <value>myTransactionInterceptor</value> <value>myProductServiceTarget</value> </list> </property> </bean> </beans>
public class ProductServiceImpl implements ProductService { private ProductDao productDao; public void setProductDao(ProductDao productDao) { this.productDao = productDao; } public void increasePriceOfAllProductsInCategory(final String category) { List productsToChange = this.productDAO.loadProductsByCategory(category); ... } ... }
一個簡便可選的創建聲明式事務的方法是:TransactionProxyFactoryBean, 特別是在沒有其他AOP interceptor牽扯到的情況下。對一個特定的目標bean,
TransactionProxyFactoryBean用事務配置自己聯合proxy定義。 這樣就把配置工作減少為配置一個目標bean以及一個 proxy bean的定義
(少了interceptor的定義)。 此外你也不需要指定事務方法定義在哪一個接口或類中。<beans> ... <bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="mySessionFactory"/> </property> </bean> <bean id="myProductServiceTarget" class="product.ProductServiceImpl"> <property name="productDao"> <ref bean="myProductDao"/> </property> </bean> <bean id="myProductService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="myTransactionManager"/> </property> <property name="target"> <ref bean="myProductServiceTarget"/> </property> <property name="transactionAttributes"> <props> <prop key="increasePrice*">PROPAGATION_REQUIRED</prop> <prop key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop> </props> </property> </bean> </beans>