Spring事务疑问:add()不回滚add2()正常回滚的原因咨询
问题原因解释
核心原因是Spring事务基于动态代理实现,内部方法调用不会触发事务切面,具体拆解如下:
调用
add()方法时:add()本身没有@Transactional注解,请求进来后直接执行原始对象的add()方法。- 调用
this.transactionalError()属于同一类内部方法调用,完全绕过了Spring生成的事务代理对象,所以transactionalError()上的@Transactional注解根本不会被Spring的事务切面识别。 - 这就导致
myService.save(myObj)执行后直接提交到数据库,后续抛出的异常无法触发回滚,最终myObj留在数据库中。
调用
add2()方法时:add2()带有@Transactional注解,请求进来时,Spring会通过代理对象执行add2()方法,此时事务已经被正常开启。- 虽然
add2()内部调用transactionalError()还是内部调用,但整个add2()方法已经处于事务上下文之中,所以transactionalError()里的所有数据库操作都属于当前事务的一部分。 - 当
"".substring(2)抛出异常时,Spring会触发事务回滚,myObj和myObj2都不会被存入数据库,符合预期。
简单总结:Spring事务注解只有在通过代理对象调用方法时才会生效,同一类内的直接方法调用不会触发代理逻辑,自然无法启用事务。
内容的提问来源于stack exchange,提问作者Chouch
相关产品推荐
相关产品推荐

