Spring嵌套事务异常记录

先来看个异常

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执行完毕事务回直接提交,需考虑业务的整体性)

你可能感兴趣的:(spring,数据库,sql)