gpt4 book ai didi

java - 并发 findAndModify 查询成功更新同一文档

转载 作者:可可西里 更新时间:2023-11-01 09:14:45 25 4
gpt4 key购买 nike

我有一个用 Java 编写并使用 MongoDB 3.4 副本集的任务 worker ,该副本集运行许多线程,每个线程基本上都在执行此操作。

  • 运行任务
  • 通过在 MongoDB 中更新该任务的文档来表示任务已完成
  • 运行查询以查看是否完成了这组任务中的所有任务
    • 如果是,继续下一阶段的处理
    • 否则什么都不做

如您所见,这里存在竞争条件;多个任务几乎可以同时完成,并认为它们是最后一个要完成的任务。我想使用 MongoDB 来确保只允许其中一个任务开始下一阶段的处理。

我有以下代码,旨在确保这些任务中只有一个可以继续(我正在使用 Jongo 与 MongoDB 交互)。

Chipset modified = chipsets
.findAndModify("{_id: #, status: {$ne: #}}", new Object[] { chipset.getId(), Chipset.Status.Queued })
.with("{$set: {status: #}}", new Object[] { Chipset.Status.Queued })
.returnNew().as(Chipset.class);

if (modified != null)
runNextProcessingStep();

这里很简单;我只是使用 findAndModify 将芯片组(任务集)的状态更改为已排队。成功进行更改的那个将执行 runNextProcessingStep()。

或者这就是我认为它应该工作的方式。实际上,有几个任务,甚至是相隔 2 秒完成的任务,都会以某种方式返回非空 modified。据我了解,MongoDB 应该在运行 findAndModify 时锁定文档,以便返回非空文档不超过一次。

我读过 Linearizable Reads via findAndModify并实现了其中所说的一切。我已将连接写入关注点设置为 Majority,将读取关注点设置为 Linearizable。我已经在 _id 和状态上创建了一个唯一的复合索引。依然没有。也许我误解了 findAndModify 的实际行为?我做错了什么?

最佳答案

好吧,这很尴尬,但为了成为一名优秀的互联网公民,我会用发生的事情更新它。还有另一个线程正在改变我下面的状态。我已经说服自己这不可能是这种情况,但是,好吧,并发有时真的很痛苦。 findAndModify 的工作方式完全符合我的预期。

关于java - 并发 findAndModify 查询成功更新同一文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48998124/

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