关于Spring嵌套事务异常问题

关于Spring嵌套事务异常问题

异常截图

在这里插入图片描述
异常信息: Transaction silently rolled back because it has been marked as rollback-only

代码展示

UserServiceImpl

@Transactional(rollbackFor = Exception.class)
public void test(){
    friendService.saveFriend(10000000000L, Arrays.asList(10000000000L));
    try {
        friendService.test();
    }catch (Exception e){
        e.printStackTrace();
    }
    System.out.println("123");

}

FriendServiceImpl

@Transactional
public void test() {
    System.out.println(1/0);
    friendRepo.deleteByUid(10000000000L);
}

UserTest

@Autowired
private UserService userService;

@Test
public void test(){
    userService.test();
}

产生原理

两个方法都加了事务注解,并且两个方法都会受到到事务管理的拦截器增强,并且事务传播的方式都是默认的,也就是REQUIRED,当已经存在事务的时候就加入事务,没有就创建事务。这里A和B都受事务控制,并且是处于同一个事务的。

A调用B,A中抓了B的异常,当B发生异常的时候,B的操作应该回滚,但是A吃了异常,A方法中没有产生异常,所以A的操作又应该提交,二者是相互矛盾的。

spring的事务关联拦截器在抓到B的异常后就会标记rollback-only为true,当A执行完准备提交后,发现rollback-only为true,也会回滚,并抛出异常告诉调用者。

抑制异常方式

1.在catch中添加TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

2.尽量不要再service中try-cache

扩展

spring的事务处理方式才用的是AOP模式,走的是代理。当内部方法嵌套调用则并不会走代理就不会产生事务嵌套异常。需要走代理则采用注入类方式调用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值