这篇文章主要介绍Spring中事务处理的方式及其实现。




读完本文你会了解到  1.Spring事务管理方式有哪些


 2.spring事务管理的具体实现


 3.各种实现之间的比较

     









Spring事务处理的方式



编程式事务管理

*在实际应用中很少使用

*通过TransactionTemplate手动管理事务

使用XML配置声明式事务

*开发中推荐使用(代码侵入性小)

*Spring的申明式事务是通过AOP实现的。



     





1、编程式事务处理具体实现





applicationContext.xml文件配置






[html]  view plain  copy


 print

?

1. <!-- 配置业务层类 -->  
2. <bean id="accountService" class="com.zs.spring.demo1.AccountServiceImpl">  
3. <property name="accountDao" ref="accountDao" />  
4. <!-- 注入事务管理的模板 -->  
5. <property name="transactionTemplate" ref="transactionTemplate" />  
6. </bean>  
7.   
8. <!-- 配置DAO类(简化,会自动配置JdbcTemplate) -->  
9. <bean id="accountDao" class="com.zs.spring.demo1.AccountDaoImpl">  
10. <property name="dataSource" ref="dataSource" />  
11. </bean>  
12.   
13. <!-- ==================================1.编程式的事务管理=============================================== -->  
14. <!-- 配置事务管理器 -->  
15. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
16. <property name="dataSource" ref="dataSource" />  
17. </bean>  
18.   
19. <!-- 配置事务管理的模板:Spring为了简化事务管理的代码而提供的类 -->  
20. <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">  
21. <property name="transactionManager" ref="transactionManager"/>  
22. </bean>






Service层具体代码实现







[java]  view plain  copy


 print

?

1. //注入事务管理的模板  
2. private TransactionTemplate transactionTemplate;  
3.   
4. /**
5.  * @param out   :转出账号
6.  * @param in    :转入账号
7.  * @param money :转账金额
8.  */  
9. @Override  
10. public void transfer(final String out, final String in, final Double money) {  

 
  
1. //这里用到了<span style="font-size: 12.6315793991089px; font-family: Arial, Helvetica, sans-serif;">transactionTemplate的execute的方法,将具体的事务管理放到了这里</span>  
2. new TransactionCallbackWithoutResult() {  
3. @Override  
4. protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {  
5.                 accountDao.outMoney(out, money);  
6. //int i = 1/0;  
7.                 accountDao.inMoney(in, money);  
8.             }  
9.         });  
10.     }


             编程式的事务处理相对来说繁琐,需要对每个使用到事务处理的类中写代码,这种方式一般使用的情况很少,大家了解下即可。







2、声明式事务处理具体实现




声明式的三种实现方式

1、基于TransactionProxyFactoryBean的方式。

2、基于AspectJ的xml方式。

3、基于注解的方式。

     



a、TransactionProxyFactoryBean方式的具体实现:

applicationContext.xml配置文件:



[html]  view plain  copy


 print

?


1. <!-- 配置事务管理器 -->  
2. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
3. <property name="dataSource" ref="dataSource" />  
4. </bean>  
5.       
6. <!-- 配置业务层的代理 -->  
7. <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
8. <!-- 配置目标对象 -->  
9. <property name="target" ref="accountService" />  
10. <!-- 注入事务管理器 -->  
11. <property name="transactionManager" ref="transactionManager"></property>  
12. <!-- 注入事务的属性 -->  
13. <property name="transactionAttributes">  
14. <props>  
15.                 <!--   
16.                     prop的格式:  
17.                         * PROPAGATION   :事务的传播行为  
18.                         * ISOTATION     :事务的隔离级别  
19.                         * readOnly      :只读  
20.                         * -EXCEPTION    :发生哪些异常回滚事务  
21.                         * +EXCEPTION    :发生哪些异常不回滚事务  
22. >  
23. <prop key="transfer">PROPAGATION_REQUIRED</prop>  
24. <!-- <prop key="transfer">PROPAGATION_REQUIRED,readOnly</prop> -->  
25. <!-- <prop key="transfer">PROPAGATION_REQUIRED,+java.lang.ArithmeticException</prop> -->  
26. </props>  
27. </property>  
28. </bean>


           这种方式虽然不在Service层附加任何代码,但是在配置的时候需要把使用到的类都注入到配置文件中,如上代码示例中的目标对象!这种方式也相对来说比较繁

琐,大家了解下即可。

b、基于AspectJ的xml配置方式






applicationContext.xml文件:



[html]  view plain  copy


 print

?

1. <!-- 配置事务管理器 -->  
2. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
3. <property name="dataSource" ref="dataSource" />  
4. </bean>  
5.   
6. <!-- 配置事务的通知 -->  
7. <tx:advice id="txAdvice" transaction-manager="transactionManager">  
8. <tx:attributes>  
9.         <!--   
10.             propagation :事务传播行为  
11.             isolation   :事务的隔离级别  
12.             read-only   :只读  
13.             rollback-for:发生哪些异常回滚  
14.             no-rollback-for :发生哪些异常不回滚  
15.             timeout     :过期信息  
16. >  
17. <tx:method name="transfer" propagation="REQUIRED"/>  
18. </tx:attributes>  
19. </tx:advice>  
20.   
21. <!-- 配置切面 -->  
22. <aop:config>  
23. <!-- 配置切入点 -->  
24. <aop:pointcut expression="execution(* com.zs.spring.demo3.AccountService+.*(..))" id="pointcut1"/>  
25. <!-- 配置切面 -->  
26. <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>  
27. </aop:config>

              这种方式利用到了Spring中的Aop,实现了自动拦截,只要Service中有出现了异常,事务都可以回滚,在配置的时候需要着重注意配置事务的隔离级别,不需

要太繁琐,这样会导致效率和性能的低下。

c、使用注解的方式:






applicationContext.xml文件:



[html]  view plain  copy


 print

?

1. <!-- 配置事务管理器 -->  
2. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
3. <property name="dataSource" ref="dataSource" />  
4. </bean>  
5.       
6. <!-- 开启注解事务 -->  
7. <tx:annotation-driven transaction-manager="transactionManager"/>

在具体使用的时候需要加上@Transactional注解。这种方式配置简单,使用起来方便。



3、小结


Spring中对事务这块提供了很多的实现方式,大家需要在了解Spring事务管理的时候,把事务这块的知识做好功课哦,这样理解起来就更加方便了。