Mongodb 如何防止多个进程读取同一文档

Mongodb 如何防止多个进程读取同一文档,mongodb,Mongodb,,我的场景是,我有一个集合,其中包含许多要处理的文档—一次一个文档。处理一个文档需要相对较长的时间,处理整个集合需要很多小时。因此,我将有多个同时处理同一集合的“工作人员”。每个人都需要这样做 (A) 获取下一个未处理的文档 (B) 处理它 (C) 将文档标记为已处理,然后继续 如何确保同时进行的过程不会读取相同的文档?我不知道关键值是什么,所以我不能说像过程A应该从1开始,过程B应该从100万开始。此外,我还想添加尽可能多的可管理流程,因此说一个向前,另一个向后是不实际的 我询问MongoDB

,我的场景是,我有一个集合,其中包含许多要处理的文档—一次一个文档。处理一个文档需要相对较长的时间,处理整个集合需要很多小时。因此,我将有多个同时处理同一集合的“工作人员”。每个人都需要这样做

(A) 获取下一个未处理的文档

(B) 处理它

(C) 将文档标记为已处理,然后继续

如何确保同时进行的过程不会读取相同的文档?我不知道关键值是什么,所以我不能说像过程A应该从1开始,过程B应该从100万开始。此外,我还想添加尽可能多的可管理流程,因此说一个向前,另一个向后是不实际的

我询问MongoDB是因为我正在使用它。我想对于SQL数据库也会问同样的问题

我恳请任何想帮忙的人,不要把注意力集中在改变情况上,无论出于何种外部原因,这都是必然的


谢谢

我建议使用一些线程安全资源来维护一组已读文档。当您的工作人员阅读文档时,他们会尝试将文档的
\u id
放到该资源中。如果不存在,则工作人员应处理该文档,如果存在,则工作人员应移动到下一个文档


至于这个线程安全资源可能是什么,Mongo实际上是一个不错的选择。它具有文档级原子性,因此您可以创建一个新的“已解析文档”集合。每次尝试解析文档时,都会将其
\u id
插入到该集合中,如果写入结果显示您插入了1个文档,那么您就知道它是新的。

您可以使用skip和limit对集合进行分区并将工作人员分配到这些分区吗?@TeTeT skip可能不是很好的选择,因为在内部skip仍然需要处理它跳过的所有文档。这将是非常低效的。在mysql的评论中有关于这个问题的讨论。我怀疑它在这里也会起作用。也许有趣?我所关心的是,在抓取文档并将其标记为正在处理之间的时间间隔内,可以通过删除文档,或者更新标志,或者在另一个集合中写入其id,-在这段时间间隔内,另一个进程也会抓取该文件。@sdo如果在Mongo确认创建了新文档之后才开始处理,则不会有任何问题。不要更新文档中的标志,只使用_id fieldGotcha创建一个新文档,-因此逻辑必须是:抓取一个文档,将其写入id集合,如果写入有效,即不重复,则处理它。否则,另一个进程将拥有它,因此继续下一个文档。并且,在处理完一个文档后,标记该文档,这样就不会有进程再次尝试它——这是因为mongo没有联接。我不能说,获取数据集合中的下一个文档,该文档的id中没有它的_idcollection@sdfor如果将_id写入它们自己的集合,则不需要任何标志。文档本身就是标志。您要查找的是insert的写入结果:如果它返回1个创建的文档,那么它是新的,应该进行处理。如果说创建了0个文档,那么另一个流程已经开始处理此文档