事务传播机制实验中出现的问题
在测试 REQUIRED 和 NESTED 区别的时候,写了如下一段代码:

然后在测试的时候,如果不捕获异常的话,无论被调用方法的传播机制是 REQUIRED 还是 NESTED,user 和 login_ticket 中的 status 都还是为 0(回滚)。
但是捕获异常的话,两种机制都不回滚,2 个表中的 status 都变成了 1。
这是为啥呢?
在技术交流群里请教了大佬之后,终于明白了(虽然也是一知半解)。
原来我把两个方法写在了同一个类里,这样当第一个方法被调用时,走了 AOP 代理;然后去调用第二个方法的时候,因为是同一个类的方法,所以方法内部调用的时候,直接是 this.xxx(),没走代理。即,代理内部调用本类的方法的时候不会重新走一遍代理。不走代理的话,需要代理才能生效的那些功能就会失效。所以下面的这个方法就成了一个普通方法。实际的效果如下:

这个时候,虽然有异常,但是被捕获了,所以事务不会回滚。
需要改成下面的形式:
(这里大佬说,可以在一个 Service 中注入另一个 Service,他公司项目中有这种写法)

把被调用方法写到另一个类(BetaService)中:

把 2 个方法写在不同的类中,就能实现 spring事务传播机制NESTED和REQUIRED的区别 这篇博客中的效果。
即,不捕获异常,无论 REQUIRED 还是 NESTED,2 个事务都会回滚;捕获异常,REQUIRED 主事务也会回滚,NESTED 主事务不会回滚,嵌套事务会回滚。具体原理可以参照上面的博客。
(不得不佩服大佬实在是太强了。Spring 底层原理日后还得多加学习)

浙公网安备 33010602011771号