java - Spring/JPA 多线程死锁

标签 java spring multithreading jpa spring-boot

我有一个依赖于 spring-boot-starter-data-jpa 的 spring-boot 应用程序。我有一个像这样的简单存储库:

import org.springframework.data.jpa.repository.JpaRepository;

public interface FooRepository extends JpaRepository<FooEntity, Integer> {
}

我有一个像这样的简单 Controller :

@RestController
public class FooController {
    private FooRepository fooRepo;

    public FooController(final FooRepository fooRepo) {
        this.fooRepo = fooRepo;
    }

    @GetMapping(value = "{id}}", produces = "application/json")
    public ResponseEntity<FooEntity> getFoo(@PathVariable("id") int fooId) {
        FooEntity ent = fooRepo.findOne(fooId);
        return new ResponseEntity<>(ent, HttpStatus.OK);
    }
}

但是我的应用程序经常遇到死锁问题。即使有 10 个用户同时尝试获取 Foo 也会导致错误:

Transaction was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

使应用程序线程中的所有数据库事务安全的最佳方法是什么?

编辑 1: 这不仅发生在获取时,也发生在保存和更新时。该问题的一种解决方案是将 Java 关键字 synchronized 添加到存储库方法中。这解决了所有死锁问题,不再担心。但这是否意味着我们必须将该关键字添加到每个 repo 方法中?是否有更可持续的解决方案?

最佳答案

正如Kayaman所说,这应该是因为写入或更新操作,但您提供的数据不能再多说了。我的猜测是一个事务在等待另一个事务结束时超时,所以它假设死锁。看看 SQL 查询日志,看看在死锁时刻正在执行什么,什么在等待,也许这可以给你一些提示。

关于java - Spring/JPA 多线程死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49305097/

相关文章:

javax.net.ssl.SSLPeerUnverifiedException : peer not authenticated after upgrading Spring Boot from 2. 1.0 到 2.2.0.M3

java - 使用 Spring 的 Web 应用程序中的每用户时区

java - Spring MVC : What happens if I start a thread in a controller action?

java - 线程服务器/客户端在第二个客户端加入后停止

java - 在 DCL 的情况下需要 volatile 关键字

java - 将字符串日期转换为 Java 日期对象

Java归并排序算法

java - 如果我尝试在 jdk6 上使用我用 jdk7 编写的类,是否会遇到问题?

java - JNI,加载2次相同的dll(不同的名称),如何选择使用哪一个?

javascript - Spring WebFlux 和 WebSocket