嵌套方法调用中@Transactional的事务行为解析
Spring事务嵌套调用行为解析
先看你给出的示例代码:
@Service public class MyService { @Transactional public void methodA() { // some database operations methodB(); } public void methodB() { // some other database operations } }
针对你提出的两个问题,直接给出结论和原因:
1. 调用methodA()时,methodB()是否在methodA()开启的同一事务中执行?
是。Spring事务基于AOP代理实现,外部调用methodA()时,Spring会生成代理对象并开启事务。而methodA()内部调用methodB()属于类内部方法调用,不会经过代理对象,此时methodB()会直接复用methodA()已开启的事务连接(Spring通过ThreadLocal将数据库连接绑定到当前线程),因此两者的数据库操作都处于同一个事务中。
2. 若methodB()中发生异常,是否会导致methodA()的事务回滚?
分三种情况判断:
- 如果
methodB()抛出RuntimeException或Error,且methodA()未捕获该异常,整个事务会触发回滚,包含methodA()和methodB()中的所有数据库操作。 - 如果
methodA()捕获了methodB()的异常但未重新抛出,事务不会回滚,因为Spring事务管理器无法感知到异常的发生。 - 如果
methodB()抛出CheckedException(受检异常),默认不会触发事务回滚,除非你给@Transactional注解配置rollbackFor属性(比如@Transactional(rollbackFor = Exception.class)),指定对所有异常都触发回滚。
内容的提问来源于stack exchange,提问作者hamdam
相关产品推荐
相关产品推荐

