失效场景
场景一
1.在一个没有@transaction方法上调用另外一个有该注解的方法,那么另外一个方法的注解将会是无效的,如下面代码中的insertUserNoTrans()方法调用有注解的insertOrder()方法。
public void insertUserNoTrans(User user){
userMapper.insertSelective(user);
TransactionTestService transactionTestService = (TransactionTestService)AopContext.currentProxy();
// transactionTestService.insertOrder();
insertOrder();
}
@Transactional
public void insertOrder(){
Student student = new Student();
student.setStudentNo("501601");
student.setScore(100d);
student.setStudentName("Transaction");
student.setSubjectNo("5001");
student.setSubjectName("计算机技术应用");
student.setCreateTime(new Date());
studentMapper.insertSelective(student);
int i = 1/0;
}
失效原理
spring的事务失效通过动态代理失效,当在自己的类中的一个方法调用另外一个方法时则相当于this调用,而不是代理类调用,代理类调用的是上一个方法,由于上一个方法没有使用注解,所以也不会有事务的功能。
解决方案
解决方案一:
1.在springboot启动类中开启自动获取事务@EnableAspectJAutoProxy(exposeProxy = true)的注解
2.使用
TransactionTestService transactionTestService = (TransactionTestService)AopContext.currentProxy();
获取代理对象,
3.使用代理对象调用目标方法(即上面例子中注释掉的方法)
注意:该解决方案能很好的帮忙理解spring事务的原理,但在实际项目中并不推荐使用。
解决方案二:
将另外的方法用另外一个Service去失效,然后注入调用即可。
场景二
事务注解只能是public方法,其他方法不生效
场景三
指定不回滚的异常时,当程序抛出该异常也是不会回滚。