gpt4 book ai didi

java - 如何删除(多线程)事务性 Spring/JPA 中的实体

转载 作者:行者123 更新时间:2023-11-30 03:02:42 31 4
gpt4 key购买 nike

假设有一个服务组件,使用 Book 实体的 CrudRepository。假设服务的方法之一应该是事务性的,并且应该(除其他外)使用事务性语义从数据库中删除一个实体(即,如果无法执行删除,则应回滚所有效果)。

大致上,

@Component
public class TraService {
@Autowired
BookRepo repo;

@Transactional
public void removeLongest() {
//some repo.find's and business logic --> Book toDel
repo.delete(toDel);
}
}

现在这应该在多线程上下文中工作,例如在 Spring MVC 中。为了简单起见,我启动了 2 个线程,每个线程都在一个任务上提供对 TraService bean 的引用。日志显示,确实创建了两个 EntityManager 并将其绑定(bind)到各自的线程。但是,当第一个线程成功删除时,另一个线程会抛出

org.springframework.orm.jpa.JpaOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1;

我不知道如何恢复(即我怀疑回滚未完成,并且线程在调用事务方法后应该执行的代码将不会被执行)。 worker 代码:

public void run() {
service.removeLongest(); //transactional
System.out.println("Code progressing really well " + Thread.currentThread()); //not executed on thread with exception
}

我们如何在 Spring/JPA 中正确处理此类事务性删除

最佳答案

简短回答:乐观锁异常的正确行为是捕获异常并重试

长答案:乐观锁定是一种互斥策略,假设

来自:https://en.wikipedia.org/wiki/Optimistic_concurrency_control

multiple transactions can frequently complete without interfering with each other

乐观锁定的存在主要是因为性能,并且通常使用一个字段来实现,该字段通过版本计数器考虑每个修改。如果在事务期间版本计数器发生变化,则意味着正在发生并发修改并导致引发异常。

悲观锁定将阻止任何可能的并发修改,更易于管理,但性能较差。

关于java - 如何删除(多线程)事务性 Spring/JPA 中的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35557554/

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