事务传播机制:
事务的传播行为是针对嵌套事务而言。即是针对(需要事务的业务方法)调用(需要事务的业务方法)。
** 注意事项:
以下案例的业务方法在不同的类下:
在同一个类下面不同的方法就算都有事务,调用的方法事务都是不会生效的。
意思是在A类的a方法调用b方法,a,b方法均有事务,直接调用b方法,事务是不会生效的。
原因是spring事务处理实际是基于动态代理生成类进行事务管理的,而直接调用b方法,调用的实际是当前类的b方法,而并非是代理类的方法,所以b方法并不能加入事务处理。**
解决方法有很多:
①:可以在当前类注入被spring管理的bean
之前直接调用
this.b()
之后先注入 A类, 最后以a.b()方式调用,事务即可生效。
@Autowired
private A a;
a.b()
②:利用aop获取当前的代理对象
AopContext.currentProxy()
回归正题。。。
@Transactional
1:REQUIRED
spring的默认传播行为。
作用:
** 支持事务,如果业务方法执行时在一个事务中,则加入当前事务,否则则重新开始一个事务。
外层事务提交了,内层才会提交。
内/外只要有报错,他俩会一起回滚。(栗子二,三)
只要内层方法报错抛出异常,即使外层有try-catch,该事务也会回滚!(栗子一)
内层不存在事务,外层存在事务,即加入外层的事务,不管内层,外层报错,都会回滚事务。**
栗子一:
条件:外层正常try-catch内层,内层出错。
结果:事务回滚,内层外层都回滚。
报错:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
外层方法
//外层正常
@Service
public class UserServiceImpl implements UserService{
@Autowired
private TeacherService teacherService;
@Override
@Transactional(rollbackFor = {Exception.class})
public int transaction() {
userMapper.add(3, 200D);
try {
teacherService.add();
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
}
内层方法
//内层出错
@Service
public class TeacherServiceImpl implements TeacherService {
@Autowired