从多个客户端查找和修改MongoDB 我的MangGDB集合用作作业队列,从该集合中读取的C++ 3台机器。问题是这三个人不能做同样的工作。所有工作只需要做一次

从多个客户端查找和修改MongoDB 我的MangGDB集合用作作业队列,从该集合中读取的C++ 3台机器。问题是这三个人不能做同样的工作。所有工作只需要做一次,mongodb,Mongodb,我通过搜索集合中具有“isDone:False”的所有记录来获取所有未完成的作业,然后更新此文档“isDone:True”。但是,如果两台机器同时找到相同的文档,它们将同时执行相同的作业。我怎样才能避免这种情况 编辑:我的问题是-findAndModify真的解决了这个问题吗? (阅读后)是,查找并修改它 参考: "... 注意:此命令在受影响的数据库上获得写锁,并将阻止其他操作,直到其完成;但是,通常写锁是短期的,与其他类似的update()操作等效。 ……” 参考: "... 对于未归档的集

我通过搜索集合中具有“isDone:False”的所有记录来获取所有未完成的作业,然后更新此文档“isDone:True”。但是,如果两台机器同时找到相同的文档,它们将同时执行相同的作业。我怎样才能避免这种情况

编辑:我的问题是-findAndModify真的解决了这个问题吗?
(阅读后)

是,查找并修改它

参考: "... 注意:此命令在受影响的数据库上获得写锁,并将阻止其他操作,直到其完成;但是,通常写锁是短期的,与其他类似的update()操作等效。 ……”

参考: "... 对于未归档的集合,可以使用$isolated isolation运算符重写此行为,该运算符将隔离更新操作并在更新期间阻止其他写入操作。请参阅isolation运算符。 ……”

参考:

问候,,
Moacy

是的,查找并修改将解决您的问题:

db.collection.findAndModify({ 查询:{isDone:false}, 更新:{$set:{isDone:true}}, 新:没错, upsert:false#永远不要创建新文档 } );

这将返回一个刚从false更新为true的文档

<>但是如果你的C++客户端有一个嗝(盒子被杀死,他们的代码有错误等等),你会有一个严重的问题,想象一下,如果你的TCP连接在服务器更新之后就掉了,但是在C++代码得到这个任务之前。通常最好采用多阶段方法:

  • 将“IsOne”更改为“isInProgress”,然后在完成后删除文档。(现在,您可以看到“待办事项”和“正在完成”的堆栈。如果某件事情“正在完成”很长时间,客户可能已经死亡

  • 将“isDone”更改为“phase”,并以原子方式将其从“new”设置为“started”(随后将其设置为“finished”)。现在,您可以看到,如果某个内容“started”很长时间,则客户端可能已死亡


如果你真的很老练,你可以做一个部分索引。例如,“只索引文档”阶段:{$ne:'finished'}"。现在,您不需要浪费空间为数百万个已完成的文档编制索引。索引只包含少数新文档/正在进行的文档,因此它更小/更快。

我对您的问题感到困惑。
findAnyModify
的全部要点是,它可以作为单个操作自动查找和修改文档,从而防止出现此问题m、 我想知道看了@EiTkoCaT之后是否真的是这样