gpt4 book ai didi

java - 微服务实例间JPA同步

转载 作者:行者123 更新时间:2023-11-30 07:43:03 26 4
gpt4 key购买 nike

我有一个基于计时器的工作

@Component
public class Worker {

@Scheduled(fixedDelay = 100)
public void processEnvironmentActions() {
Job job = pickJob();
}

public Job pickJob() {
Job job = jobRepository.findFirstByStatus(Status.NOT_PROCESSED);
job.setStatus(Status.PROCESSING);
jobRepository.save(job);
return job;
}
}

现在,在大多数情况下,这应该会给我正确的结果。但是如果有两个微服务实例同时执行这段代码会怎样呢?

我如何确保即使有多个服务实例,存储库也应该始终只将一项工作分配给一个实例而不是其他实例。

编辑:我认为人们对 @Transactional 感到困惑/专注,因此将其删除。问题还是一样。

最佳答案

But what will happen if there are two instances of microservice executing this piece of code at the same time?

答案通常是:视情况而定。

所有这些都假设您的代码在事务中运行

  1. 乐观锁。

    如果您的 Job 实体具有版本属性,即用 @Version 注释注释的属性。启用乐观锁定。如果进程访问同一个作业,在尝试保留更改的作业实体时会注意到版本属性已更改,并因 OptimisticLockingException 而失败。您所要做的就是处理该异常,这样您的进程就不会死掉,而是再次尝试获取下一个Job

  2. 无(JPA 级)锁定。

    如果 Job 实体没有版本属性,JPA 将默认不应用任何锁定。访问 Job 的第二个进程将发出一个更新,本质上是一个 NOOP,因为第一个进程已经更新了它。两者都不会注意到问题。您可能想避免这种情况。

  3. 悲观锁

    pessimistic_write 锁将阻止任何人在您完成读写之前读取该实体(至少这是我对 JPA 规范的理解)。因此,这应该避免第二个进程能够在第一个进程完成写入之前选择该行。这可能会阻止整个第二个过程。所以要确保持有这种锁的事务是短的。

    为了获得这样的锁,请使用 @Lock(LockModeType.PESSIMISTIC_WRITE) 注释存储库方法 findFirstByStatus

当然,可能有一些库或框架可以为您处理这些细节。

关于java - 微服务实例间JPA同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53829660/

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