【问题标题】:Save the same instance twice in a transaction with updated values在具有更新值的事务中保存相同的实例两次
【发布时间】:2020-04-21 17:15:50
【问题描述】:

我正在 Spring Boot 中编写一个多线程 cron 作业。我有一个需要对其执行某些操作的用户列表。下面是来自 cron 作业的 sn-p

public void executeCronJob() {
    LOG.debug("Started >>>");
    User user = userService.findFirstNotInProgress();
    if (user == null) {
        LOG.debug("<<< User not found");
        return;
    }
    userService.updateStatus(user, Status.IN_PROGRESS);
    someOtherService.doSomeActionRelatedToUser(user);
    userService.updateStatus(user, Status.COMPLETED);
    LOG.debug("<<< Completed");
}

UserService.java

private void updateStatus(User user, Status status) {
    user.setStatus(status);
    userRepository.save(user);
}

我正在使用多线程,因为someOtherService.doSomeActionRelatedToUser(user); 方法可能需要相当长的时间,因此会阻止其他用户的执行。第一次调用userService.updateStatus 工作正常,用户进入 IN_PROGRESS 状态。但是在对与用户相关的someOtherService 执行操作后,当我再次调用userService.updateStatus 将状态设置为COMPLETED时,我收到错误

行被另一个事务更新或删除(或未保存值映射不正确)

我尝试在 UserService 中使用 userRepository.saveAndFlush(user);,但它仍然给我同样的错误。我该如何解决这个问题?

【问题讨论】:

  • 看起来不止一个线程试图更新同一个实体,一个线程成功,当下一个线程去提交数据时,它看到它已经被修改并最终抛出错误。

标签: java multithreading spring-boot cron transactions


【解决方案1】:

我认为您需要确保只有一个线程访问代码块 [如下所示] 以获取用户状态并将状态更新为进行中。您必须同步以下代码块。

User user = userService.findFirstNotInProgress();
if (user == null) {
    LOG.debug("<<< User not found");
    return;
}
userService.updateStatus(user, Status.IN_PROGRESS);

【讨论】:

  • 这就是问题所在。我需要多个线程来访问给定的代码块,以便每个线程可以在不同的用户上工作。不应该只在访问同一个用户实例时才会出现同步问题吗?
  • 您只能同步我评论中提到的代码块。这将确保 findFirstNotInProgress 用户不会被多个线程同时读取。多线程仍然可以访问 doSomeActionRelatedToUser 方法
【解决方案2】:

您将与会话关联的user 传递给多个线程,并且由于 Hibernate Session 对象不是线程安全的,您最终会遇到此错误。

您可以在 doSomeActionRelatedToUser() 中使用新会话而不是 executeCronJob() 将状态更新为 COMPLETED。

或者您可能希望someOtherService.doSomeActionRelatedToUser(user); 返回CompletableFuture,然后更新状态。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多