首先要知道Spring事务的原理。
当我们在一个类上加了@Transactional注解后,就表示该方法是需要Spring帮我们开启事务的。
所以这个方法所在的类所对应的Bean对象一定是该类的代理对象。
Spring事务的代理对象执行某个方法时是如下流程:
1.判断当前执行的方法是否存在@Transactional注解.
2.如果存在,直接利用TransactionMananger新建一个数据库连接.
3.autocommit修改位false(就不是自动提交了)
4.执行target对象中加了@Transactional注解的方法(这里指的target是代理对象中放的经历了一个完整bean生命周期的bean对象)
5.手动提交,方法中有异常则回滚。
伪代码:
try{
setAutocommit(false);
//执行注释了@Transactional的方法
target.execute();
commit();
}catch(Excption e){
回滚
}
所以,判断一个事务是否会失效的判断标准:某个加了@Transactional注解的方法被调用时,只需要判断一个方法是不是直接被代理对象调用的,如果不是,则会失效。
举两个例子就能理解上面那段话了:
1.@Transactional的方法是private方法
这种比较好理解,谁TM能在一个类中直接调用另外一个类的private方法?所以代理的时候是肯定不会重写aaa()方法的。事务自然就不会生成。
2.直接内部调用
代理对象只重写了sss()方法,并没有重写aaa()方法,所以调用方法aaa()的时候,没有生成事务。而aaa()在调用sss()的时候,由于只是简单的内部调用,所以也不会生成事务,结果就是事务失效了。