Java Spring @Transactional 方法未按预期回滚 [英] Java Spring @Transactional method not rolling back as expected

查看:18
本文介绍了Java Spring @Transactional 方法未按预期回滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我正在尝试做的事情的简要概述.我想通过一个方法调用将一条记录推送到数据库中的两个不同表.如果有任何失败,我希望一切都回滚.因此,如果 insertIntoB 失败,我希望回滚 insertIntoA 中提交的任何内容.

Below is a quick outline of what I'm trying to do. I want to push a record to two different tables in the database from one method call. If anything fails, I want everything to roll back. So if insertIntoB fails, I want anything that would be committed in insertIntoA to be rolled back.

public class Service {
    MyDAO dao;

    public void insertRecords(List<Record> records){
        for (Record record : records){
            insertIntoAAndB(record);
        }
    }

    @Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void insertIntoAAndB(Record record){
        insertIntoA(record);
        insertIntoB(record);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertIntoA(Record record){
        dao.insertIntoA(record);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertIntoB(Record record){
        dao.insertIntoB(record);
    }

    public void setMyDAO(final MyDAO dao) {
        this.dao = dao;
    }
}

其中MyDAO dao是一个接口,使用mybatis映射到数据库,使用Spring注入设置.

Where MyDAO dao is an interface that is mapped to the database using mybatis and is set using Spring injections.

现在如果 insertIntoB 失败,来自 insertIntoA 的所有内容仍然会被推送到数据库.我该如何纠正这种行为?

Right now if insertIntoB fails, everything from insertIntoA still gets pushed to the database. How can I correct this behavior?

我修改了课程以更准确地描述我要实现的目标.如果我直接运行 insertIntoAAndB,如果有任何问题,回滚工作,但如果我从 insertRecords 调用 insertIntoAAndB,回滚不会'如果出现任何问题,则无法正常工作.

I modified the class to give a more accurate description of what I'm trying to achieve. If I run insertIntoAAndB directly, the roll back works if there are any issues, but if I call insertIntoAAndB from insertRecords, the roll back doesn't work if any issues arise.

推荐答案

我找到了解决方案!

显然 Spring 无法拦截对事务方法的内部方法调用.于是把调用事务方法的方法取出来,放到一个单独的类中,回滚就好了.以下是修复的粗略示例.

Apparently Spring can't intercept internal method calls to transactional methods. So I took out the method calling the transactional method, and put it into a separate class, and the rollback works just fine. Below is a rough example of the fix.

public class Foo {
    public void insertRecords(List<Record> records){
        Service myService = new Service();
        for (Record record : records){
            myService.insertIntoAAndB(record);
        }
    }
}

public class Service {
    MyDAO dao;

    @Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void insertIntoAAndB(Record record){
        insertIntoA(record);
        insertIntoB(record);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertIntoA(Record record){
        dao.insertIntoA(record);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertIntoB(Record record){
        dao.insertIntoB(record);
    }

    public void setMyDAO(final MyDAO dao) {
        this.dao = dao;
    }
}

这篇关于Java Spring @Transactional 方法未按预期回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆