Spring声明式事务
Posted 骑着乌龟去看海
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring声明式事务相关的知识,希望对你有一定的参考价值。
1. 首先spring声明式事务的实现是通过AOP来实现的。spring声明式事务有多种方式来声明,其中最常用的是使用Spring的tx命名空间和@transactional注解来实现。
2. 在spring XML配置文件中,使用tx命名空间来配置spring事务,当然,aop一般也是要声明的,因为有一些声明式的事务配置元素是依赖于Spring的AOP配置元素;
- 我们可以使用tx:advice来配置事务,但更多的时候我们通过注解来实现,即tx:annotation-driven;
- tx:annotation-driven,默认会自动使用名称为transactionManager的事务管理器,所以,如果定义的事务管理器名称为transactionManager,那么就可以直接使用<tx:annotation-driven/>,不用手动设置manager="transactionManager" 属性;
3. spring同一个类中transactional注解无效分为两种情况:
a. 外部方法调用A方法:这种情况下B的事务将不生效;
public class Test { public void A() { this.B(); } @Transactional public void B() { System.out.println(); } }
b. 外部方法调用A方法:这种情况下B的事务将不生效;
public class Test { @Transactional(propagation=Propagation.SUPPORTS) public void A() { this.B(); } @Transactional(propagation=Propagation.REQUIRED) public void B() { System.out.println(); } }
c. 原因是Spring的AOP是使用了一个代理对象来包装目标对象,并拦截目标对象的方法调用。这样的实现带来的影响是: 在目标对象中调用自己类内部实现的方法时,spring会为该方法所在的bean动态的生成一个代理类,当这个方法被调用时,实际上是代理类调用的,如果该方法有transactional注解,代理类在调用之前就会启动transactional,如果没有,代理类就不启动事务。然而,如果这个有注解的方法是被同一个类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过原来的那个bean,所以就不会启动transaction,我们看到的现象就是@Transactional注解无效。
d. 解决方法,可以把这两个方法放到两个类中进行调用;也可以使用 AspectJ 模式的事务实现:<tx:annotation-driven mode="aspectj"/>
以上是关于Spring声明式事务的主要内容,如果未能解决你的问题,请参考以下文章