事务问题 Transaction rolled back because it has been marked as rollback-only

Transaction rolled back because it has been marked as rollback-only 的中文翻译是:事务已回滚,因为它已标记为仅回滚。??????越看越懵...

🔴其实很简单,一般就一种情况:你某一个代码块使用了try catch

下面我来举列子说明一下出现的情况吧

A实现类的方法

    @Transactional(rollbackFor = Exception.class)
    public void A(Boolean bool) {
        try {
            workItemTemplateHistoryService.B(bool);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

B实现类的方法

    @Transactional(rollbackFor = Exception.class)
    public void B(Boolean bool) throws BizException {
        if (bool) {
            throw new BizException("我是故意抛出的异常");
        }
    }

前提条件是保证A方法和B方法事务时生效的:不同一个实现类且都加上事务注解。
A方法调用了B方法,并且进行try拦截异常。
执行结果:

企业微信截图_1678957277700.png

企业微信截图_16789572602250.png

我们会发现有两处异常日志,为什么会这样呢?这是我们这次需要了解的。

当A方法的事务(REQUIRED),B方法的事务(REQUIRED),A调用B方法,在spring中,spring将会把这些事务合二为一。
当整个方法中每个子方法没报错时,整个方法执行完才提交事务。
如果某个子方法有异常,spring将该事务标志为rollback only。如果这个子方法没有将异常往上抛,或者主父方法将子方法抛出的异常捕获了,那么,该异常就不会触发事务进行回滚,事务就会在整个方法执行完后就会提交,这时就会造成Transaction rolled back because it has been marked as rollback-only的异常。(由于异常被标记了rollback only,但是又执行了commit,此时就会报这个错)

这里我提供两种解决办法:
1.去掉方法A try 方法B的异常拦截
2.关闭方法B的事务(如果方法B被其它方法调用,则重载一个没有事务的方法B)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容