spring 声明式事务中使用try catch捕获异常时分析

最近遇到这样的问题,使用spring时,在业务层需要捕获异常(特殊需要),当前一般情况下不需要这样做的。具体如下: 

在ServiceA类中有method1,在该方法中调用另一个ServiceB类的method2方法时(假定该方法抛出异常),method1方法捕获该异常但是没有向上抛出。spring提示:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only 

以下是ServiceA的示例代码 
@Transactional(rollbackFor = Throwable.class)//默认事务传播方式required 
public Class ServiceA { 
    
    @Autowired  
    private Dao dao; 

    @Autowired  
    private ServiceB serviceB;  // 注入另一Service Bean 
    
    public void method1() { 

        dao.insert(vo);  // 保存ServiceA的vo对象 
        try { 
            serviceB.method2(vo); // 保存ServiceB的vo对象 
        } catch (CustomException e) { 
            // 捕获自定义异常,但是没有向上抛出 
        } 

    } 



以下是ServiceB的示例代码 
@Transactional(rollbackFor = Throwable.class)//默认事务传播方式required 
public Class ServiceB { 
    
    @Autowired  
    private Dao dao; 
    
    public void method2() throws CustomException { 

        dao.insert(vo);  // 保存ServiceA的vo对象 
    } 


出现以上原因是spring执行method1方法时,开启一个新的事物,当调用method2方法时,当method2方法加入到method1方法的当前事务,当method2抛出异常,spring标记事务为回滚状态,method1方法捕获该异常,但没有抛出,spring会提交method1的事务,但spring发现该事务已经标记为回滚状态,而代码中却要提交事务,所以才会抛出以上的异常,method1和method2的插入方法插入数据库都会失败。 


解决的方法:在ServiceB的method2方法上注解,告诉spring当该方法抛出自定义异常CustomException时,不要回滚事务,这样当该方法抛出异常时,spring不会标记事务为回滚状态。 
@Transactional(noRollbackFor=CustomException.class) 
public void method2() throws CustomException{ 
}

参考:https://blog.csdn.net/weixin_39625809/article/details/80708340 

https://www.cnblogs.com/aurawing/articles/1887030.html

https://blog.csdn.net/hcmony/article/details/77850183 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值