Spring事务传播机制
一、何为Spring传播机制:
Spring事务的传播机制就是,事务如何在方法的调用如何传播。
二、使用传播机制的时候的关键点:
-
使用声明式的事务时,调用方法和被调用方法不能在同一个类。比如同在一个service方法中,这样是不会生效的。Spring的事务分为编程式和声明式的注解,我们一般使用声明方式的注解,利用@Transactional注解标记需要使用事务的类,Spring会利用AOP为我们在方法执行前启动事务,接受后提交和关闭事务。而AOP是基于动态代理的实现,生成代理对象,调用代理对象实现事务,而在同一个类中的调用,就会在这个类的对象调用this.method(),没有用到代理,也不会有事务。
-
使用Spring事务的方法需要被Spring所管理。不然Spring无法通过AOP生成事务。
-
确保Spring开启事务支持。
三、理解事务传播机制的角度(个人见解)
刚开始,学习这个Spring事务传播机制的时候,一直纠结调用方法和被调用存在事务这一概念。其实如果从被调用的角度看存在和不存在事务,就能很好的理解这些传播机制。通过下面一些测试,我先猜想结果,在验证结果,也能证实自己是否理解了Spring事务的传播。
四、Spring事务传播的七种方式
ps:测试其中方式的例子都是同一个,就是一个用户修改方法,修改用户名称;一个插入修改日志的方法,插入修改日志,在修改方法内调用插入日志的方法,目的是让两个数据库操作具有原子性,所以应用事务。同时利用除数为0创造异常,更好的测试。
一、REQUIRE
@Override
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Throwable.class)
public void updateUserName(String userName) {
User user = new User();
user.setId(1);
user.setUserName(userName);
userMapper.updateUserName(user);
userChangeLogService.saveLog(user.getId());
}
@Override
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Throwable.class)
public void saveLog(Integer userId) {
UserChangeLog userChangeLog = new UserChangeLog();
userChangeLog.setOpratorUserId(userId);
userChangeLogMapper.insert(userChangeLog);
int i = 10 / 0;
}
两个方法都是才有默认的事务传播属性Propagation.REQUIRED
Propagation.REQUIRED:如果当前存在事务,那么就加入这个事务,不存在就新建一个事务。
结果:这里也是两个方法都没有将操作成功,因为REQUIRE的事务传播机制下,调用者存在了一个事务,被调用者在已经存在事务的情况下,加入调用者这个事务,而不自己新创建,所以两者在同一事务种,被调用方法发生异常,整个事务回滚,都不操作成功。
SUPPORTS
Propagation.SUPPORTS:如果当前有事务,加入事务,如果没有则不使用事务
@Override
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Throwable.class)
public void updateUserName(String userName) {
User user = new User();
user.setId(1);
user.setUserName(