gpt4 book ai didi

java - JPA事务处理

转载 作者:行者123 更新时间:2023-12-02 04:17:01 25 4
gpt4 key购买 nike

我有一个 Foo 实体,其中包含字段 NameSecondaryNameCounter。在数据库中,我对(名称、次要名称、计数器)有一个唯一的约束。

在服务层中,我有以下方法(其中 fooRepositryCrudRepository):

 @Transactional(isolation = Isolation.SERIALIZABLE, propagation = Propagation.REQUIRES_NEW)
public void saveFoo(Foo foo) {
Optional<TestDto> fooWithHighestCounter= fooRepository.
findTopByNameAndSecondaryNameOrderByCounterDesc(foo.getName(), foo.getSecondaryName());

if (fooWithHighestCounter.isPresent()) {
foo.setCounter(fooWithHighestCounter.get().getCounter() + 1);
} else {
foo.setCounter(1);
}

Foo saved = fooRepository.save(foo);
}

每次调用 saveFoo 时,都会在数据库中创建一条新记录,其中现有的最高计数器 + 1。因此,必须找到最高计数器,因此 @Transactional .

但是,当多个线程调用 saveFoo 方法时,我会不断收到 ContraintViolationException,因为每个线程都找到相同的最高计数器值。

我假设每个线程都会创建一个新事务,并且这些事务将串行运行,因此没有事务会找到相同的计数器值。 (@EnableTransactionManagement 放在应用程序上)

我还能做什么来实现上述行为?

最佳答案

我认为 fooRepository.save(foo) 最后一次又一次地在数据库中保存相同的值,这就是它给出 ContrainViolationException 的原因。如果您需要将值更新为任何现有对象,只需调用 setCounter 但不要调用 .save() 方法,而是调用存储库的 update 方法(如果有),否则如果它是数据库中尚不存在的新实体,然后调用 save 方法。

如果是在 hibernate 中完成,请参阅以下链接

引用号:http://www.objectdb.com/java/jpa/persistence/update

关于java - JPA事务处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33199044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com