当前位置: 首页 > 面试题库 >

Java Spring @Transactional方法未按预期回滚

丁正阳
2023-03-14
问题内容

以下是我要做什么的快速概述。我想从一个方法调用将记录推送到数据库中的两个不同表。如果有任何失败,我希望一切都回滚。因此,如果insertIntoB失败,我希望将提交的任何内容insertIntoA回滚。

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注入设置的。

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

编辑:

我修改了该类,以更准确地描述我要实现的目标。如果我insertIntoAAndB直接运行,则在出现任何问题时回滚都有效,但是如果我insertIntoAAndB从调用insertRecords,则在出现任何问题时回滚将不起作用。


问题答案:

我找到了解决方案!

显然,Spring无法拦截对事务方法的内部方法调用。因此,我取出了调用事务方法的方法,并将其放入一个单独的类中,并且回滚效果很好。下面是该修复程序的粗略示例。

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;
    }
}


 类似资料:
  • 根据以下文档:http://testng.org/doc/documentation-main.html “如果测试类上有一个方法tearDown(),那么在每个测试方法之前和之后都会调用它”(JUnit 3) 我使用的是JUnit版本:3.8.1 这里的这个是在我的测试之前运行的,但我希望它会在测试之后。它在测试后没有运行: 我可以通过将第一行更改为: 但是,下一个类(下面)的表示法与第一个类完

  • 我正在尝试用Java编写一个进程,该进程并发执行一系列任务,等待任务完成,然后将整个进程标记为完成。每个任务都有自己的信息,包括单个任务何时完成。我将使用ExecutorService作为流程,并将流程的本质归纳如下: 每个MyRunnable对象都有一个run方法,该方法进行webservice调用,然后将调用的结果写入数据库,包括调用完成的时间。ComplethisProcess方法只是将整个

  • 我正在学习AOP Spring并尝试一些示例。关于@AfterBack ning,我所理解的是,只有当目标成功返回并且与切入点匹配时,才会调用该方法。然而,在我的例子中,如下所示,我有一个切入点,它定义了所有只返回字符串的方法,但它调用了所有空方法以及返回字符串的方法。 我的建议: 请在下面找到我的Impl课程: 请在下面找到我的MainApp类: 我原本希望只调用getCustomer(),因为

  • 我能够在iothub消息(从云到设备的消息)上打开一个侦听器,但我无法订阅direct方法。我尝试使用mqtt支持,而不是iothub库 我已经跟踪https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-direct-methods#mqtt但一定有一个小细节我还没有设法做到正确 这是我的代码(python)

  • 问题内容: 我有两个使用的示例。首先是对回调函数的引用。第二个有一个箭头函数声明为该值。 第一个按预期工作。但是,第二个在连续渲染中记录a 。 这是什么原因呢? 开始在输入框中输入内容 示例1(工作正常) 示例2(这不起作用) 问题答案: 关于React的Github问题已经对此进行了简要讨论。我会尽力解释这一点,但是很难用语言表达。 由于在第二个示例中您没有调用“智能”组件方法,因此每次重新渲染

  • 在我的flatter应用程序中,我试图在异步函数完成后使用whenComplete()方法运行一些代码。问题是whenComplete()方法中的代码甚至在异步函数完成之前就被执行了。 我也尝试过使用then()方法,这也产生了相同的结果。 这是我在其中调用异步函数的init函数: 这是异步函数的函数体: 运行应用程序时的控制台输出为: 因此,在调用异步函数getUserHomes的init()函