微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

循环 jpa 流结果的项目并调用更新服务 Envers 为所有项目创建一个修订版,而不是为每个项目

如何解决循环 jpa 流结果的项目并调用更新服务 Envers 为所有项目创建一个修订版,而不是为每个项目

我遍历 jpa 流结果的人员实体,并为每个人调用更新服务 bean 以更新人员实体的名称。我知道, envers 在交易结束时执行。好的,这工作正常,所有实体都已更新并具有 AUD 表条目,但对所有实体进行了单一修订。

我如何告诉 spring 为每个人实体做一个单一的事务,以便 envers 为每个更新的实体写入一个更新修订而不是所有更新的个人实体?我还尝试将 @Transactional(propagation = Propagation.REQUIRES_NEW) 放在更新服务类的顶部,但不是每个项目都触发 envers。似乎所有更新都在一个事务中执行,但每次调用更新服务 bean 时我都需要一个事务。

流服务:

@Service
class StreamService {

    @Autowired
    PersonRepository repo;

    @Autowired
    FooService fooService;

    @Transactional
    public void uppercaseAllNames() {
        Stream<Person> stream = repo.findAllPersons();
    
         // change name for each person
        stream.forEach(fooService::doFoo);
    }

}

简化的更新服务:

@Service
@Transactional(propagation = Propagation.REQUIRES_NEW) // <=== create new transaction
class FooService {

    @Autowired
    PersonRepository repo;

    doFoo(Person person) {
        String name = person.getName();
        person.setName(name.toupperCase());
        repo.save(person); // <=== save trigger envers
    }
}

解决办法: 保存操作会触发创建每个人实体的修订,但此解决方案仅适用于我们的项目 @Transactional(propagation = Propagation.REQUIRES_NEW)。单个 @Transactional 不起作用。注释可以放在方法或类级别,展位工作。

解决方法

@Transactional 中删除 uppercaseAllNames。 这将为您提供单独的读取和每次写入事务。

您需要将 personRepo.save(person) 添加到 FooService.doFoo 以保持更改。

对于 Propagation.REQUIRES_NEW,第二个更改可能就足够了,但我发现嵌套事务相当混乱,建议避免使用它们。

,

有同样的问题,上面的接受的答案有效。但我必须将 readOnly=true 添加到外部交易中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?