Spring嵌套事务异常记录

发布时间:2024年01月02日

先来看个异常

org.springframework,transaction,UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

下面看看抛出此异常的伪代码

@Slf4j
@Service
public class A {

    @Resource
    private B b;

    @Transactional(rollbackFor = Exception.class)
    public void aMethod(){
        try{
            b.exec();
        } catch (Exception e){
            log.info("异常打印");
        }
        //业务要求,b.bMethod() 抛出异常后 原业务需要继续执行
    }
}
@Service
public class B {

    @Transactional(rollbackFor = Exception.class)
    public void exec(){
        // 业务执行 可能抛出异常
    }

}

原因:

????????A调用B,如果B抛出Exception,A中捕获Exception但是并不继续向外抛出,最后会出现此异常。

????????纠其原理其实很简单,在B返回的时候,transaction被设置为rollback-only了,但是A正常消化掉,没有继续向外抛。 那么A结束的时候,transaction会执commit操作,但是transaction已经被设置为 rolback-only了。?

上面解释了抛出此异常的原因,下面来分析在此业务场景下如何解决这个问题:
????????因业务要求,B.exec抛出异常后原业务需要继续执行,所以这里不能就不能直接将异常抛出,需要将B.exec上的事务注解去除,将嵌套异常给断开

? ? ? ? 注:若B.exec业务可以单独在自己的事务中执行,那么可以新开事务(注意:若新开事务,B.exec执行完毕事务回直接提交,需考虑业务的整体性)

文章来源:https://blog.csdn.net/weixin_44700876/article/details/135247555
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。