【问题标题】:Spring JPA save not always executed on DBSpring JPA 保存并不总是在 DB 上执行
【发布时间】:2020-04-18 16:43:47
【问题描述】:

我正在使用 Spring JPA 存储库来处理数据库上的一些数据。

public List<DHData> editDHData(int id, DHData dhData){
    DHEntity e = dhRepository.findById(id).get();
    int val = e.findDHData(dhData.getDec1(),dhData.getDec2());
    if(val >= 0) {
        e.getDHData().get(val).setEval(dhData.getEval());
        System.out.println(val);
        dhRepository.save(e);
    }
    return e.getDHData();
}

基本上我得到了整个实体,改变了我需要改变的东西,然后我使用 JPA 保存它。 显然,当我在同一个实体上收到非常快的请求时(我们正在使用一个 Angular 前端,它一个接一个地发送这种类型的请求而没有超时),它似乎无法处理并且通过数据库我只能保存最后请求。

有没有办法让每个调用都保持一致,从而一个接一个地执行而不被跳过?

示例

我的 DHEntity 包含(连同其他信息)以下数据,我正在使用 editDHData 方法访问和修改这些数据。

{ "dec1": 1, 
 "dec2": 2, 
 "eval": 0},
{ "dec1": 1, 
 "dec2": 3, 
 "eval": 0},
{ "dec1": 2, 
 "dec2": 3, 
 "eval": 0}

我上面贴的方法,执行3次改变值

第一次通话:

{ "dec1": 1, 
 "dec2": 2, 
 "eval": 0.5}

第二次通话:

{ "dec1": 1, 
 "dec2": 3, 
 "eval": 1}

第三次调用:

{ "dec1": 2, 
 "dec2": 3, 
 "eval": 8}

每次通话后,我都会保存实体。只保留最后一个电话,因此这就是我最后得到的:

    { "dec1": 1, 
     "dec2": 2, 
     "eval": 0},
    { "dec1": 1, 
     "dec2": 3, 
     "eval": 0},
    { "dec1": 2, 
     "dec2": 3, 
     "eval": 8}

显然这些方法被调用了 3 次,但只有最后一个被保存到数据库中。 我可以对实体/存储库做些什么来确保它有效且一致吗? 数据库是 PostgreSQL,前端是 Angular(但我怀疑它是否相关)。当我通过 Postman 拨打电话时(当然要花更多时间),它工作正常。

另外,我认为可能是因为该方法不是“线程安全的”。如果每个调用都由不同的线程执行,我认为它首先将实体读取为未修改,然后在保存时将其覆盖。我需要所有操作都是顺序的,并确保数据库的持久性(这不会​​发生)

【问题讨论】:

  • 你可以在这里发布你的实体类吗?
  • @Shoshi 是的,这里是:pastebin.com/raw/XEVcENZq 我省略了方法和构造函数以使其更短
  • 你100%确定在这三个调用中每次if的条件都满足了吗?
  • 是的,这只是为了检索数组的 id(并检查它是否为正且存在)。正如我所说,如果单独进行通话,每次通话都能完美运行。当快速连续完成时,他们会遇到问题。我相信这是一个交易问题或什么的。我只是不知道如何解决它
  • 阅读:dzone.com/articles/… 你需要Pessimistic Lock

标签: java angular spring spring-boot spring-data-jpa


【解决方案1】:

确实,您的后端 Spring 应用程序是多线程的,并且每个请求使用一个线程,因此您的请求不一定按顺序发生。

正如@Shoshi 指出的那样,您需要对数据库更新进行悲观锁定,以确保更新按照接收到的顺序完成,并且每次更新在执行下一个更新之前完成。

但是,我也会更仔细地研究前端。您的前端正在为相同的数据发送一系列更新请求这一事实对我来说听起来很奇怪。在前端聚合变化,然后向后端发送一个更新请求可能会更好。

【讨论】:

  • 由于我整晚都在解决这个问题,我得出了相同的结论:首先我尝试将事务隔离设置为可序列化,并使用 Spring Retry 重试几次调用(否则我只是得到了例外,但结果没有任何变化)。然后我决定汇总所有更改并发送一个请求(这样我就可以避免这种混乱)。让我烦恼的是,我无法通过正确设置交易来解决,但最终它不值得再头痛了
猜你喜欢
  • 1970-01-01
  • 2021-09-19
  • 2020-10-21
  • 2023-01-12
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
相关资源
最近更新 更多