2013年8月3日星期六

Spring Foundation series - Transaction Transaction

 

senior management of the affairs of the spring abstraction layer contains three main excuses: TransactionDefinition, PlatformTransactionManager, TransactionStatus

 

TransactionDefinition used to describe the isolation level, the timeout, whether it is read-only transactions and transaction propagation rules

 

TransactionStatus transaction on behalf of a specific operating state, and the preservation of points

 

PlatformTransactionManager a high-level interface contains three methods commit, rollback and getTramsaction

 

transaction propagation level:

 
  
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。适用于save、update、delete等操作 
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。一般读db的操作可是使用此方式,同时将事物设置为ReadOnly。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。适用于优先级别很高的方法。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
 
 

three transaction management: programmatic transaction management, declarative transaction using xml configuration, configuring declarative transactions using annotations

 

1. programmatic transaction management

 

slightly

 

2. use xml configuration declarative transaction

 

transaction attribute information to configure rules

 
  
<!-- 传播行为,隔离级别(可选),是否为只读(可选),发生这些异常时回滚(可选),发生这些异常时照样提交(可选)--> 
<prop>PROPAGATION,ISOLATION,readOnly,_Exception,+Exception</prop>
 
 

 

first: our most commonly used method, and it applies to your database table is relatively small in the case.

 
  
<bean id="fundServiceDAOProxy" 
class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事务管理器 -->
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<!-- 此属性指定目标类本省是否是代理的对象,如果目标类没有实现任何类,就设为true代表自己 -->
<property name="proxyTargetClass">
<value>false</value>
</property>
<!-- 目标实现的接口 -->
<property name="proxyInterfaces">
<value>com.jack.fund.service.IFundService</value>
</property>
<!-- 目标bean -->
<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>
 
 

The following may be other xxxServiceDAOProxy. everyone can see that for each business function modules to configure a proxy service. If the module is more big, the code becomes a bit more and found them just a little bit different. Then we should think of the idea of ​​inheritance. Use the second method.

 

second: Configure declarative transaction as follows. This module is relatively more suitable for use.

 
  
<!-- 利用继承的思想简化配置,要把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>
 
 

and specific modules can be simply configured such. Just specify its parent (the parent class) on it. Parent generally the abstract = "true", because it does not need to load the container initialization when used again until its subclasses call, go initialized.

 
  
<bean id="fundServiceDAOProxy" parent="transactionBase" > 
<property name="target">
<ref bean="fundService" />
</property>
</bean>
 
 

configured to do so, if there are multiple like fundService this module, you can repeat a lot less code.

 

third: Configure declarative transaction as follows. Automatically creates a transaction using mainly BeanNameAutoProxyCreator 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>
 
 

main advantage of this method is the principle of interceptors.
The first three methods are generally required to specify a specific module bean. If the module is too much, then, for example, a large site usually has dozens of modules. We have to consider the configuration of the fourth. Automatically create a transactional proxy approach.

 

fourth: Configure declarative transaction as follows.

 
  
<bean id="transactionInterceptor" 
class
="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<!-- 自动代理 -->
<bean id="autoproxy"
class
="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 可以是Service或DAO层(最好是针对业务层*Service) -->
<property name="beanNames">
<list>
<value>*Service</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
 
 Another

automatic proxy usage is a combination of regular expressions and advice to use.

 
  
<bean id="transactionInterceptor" 
class
="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<bean id="autoProxyCreator"
class
="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
<bean id="regexpMethodPointcutAdvisor"
class
="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="transactionInterceptor" />
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>
 
 

This method can be carried out for a specific module to intercept and handle transaction processing.
in your actual project, you can choose according to your situation in different ways.

 

Details: http://www.cnblogs.com/rushoooooo/archive/2011 / 08/28/2155960.html

 

3. Configure declarative transactions using annotations @ Transaction

 

annotation itself has some of the commonly used default properties, so often just add an @ Transaction on it

 

@ Transaction annotation Property Description

 

value : can bind to different transaction manager

 

propagation : transaction propagation behavior

 

isolation : transaction isolation level

 

readOnly : whether it is read-only

 

timeout : Timeout

 

rollbackFor : a set of exception classes that are rolled back when the type is Class

 

rollbackForClassName : a set of exception classes that when a rollback of type String [], default is {}

 

noRollbackFor : a set of exception classes that are not rolled back when the type is Class

 

noRollbackForClassName: a set of exception classes that are not rolled back when the type is String [], default is {}

 

 

 

1 条评论: