2013-05-02 136 views
1

我在当前项目中遇到了mongo更新问题。我们在MongoDB中维护了一个文档池。阅读器进程从该池中提取一批文档。为了确保来自DB的文档不被再次提取,与每个文档相关联的状态被改变(例如,从已到达到正在处理)。是否有可能在MongoDB中进行原子批量更新?

我们正在考虑扩大规模,并有多个读取器进程捡起不同的批次。但是,根据我的理解,mongo更新在批处理中不是原子的。是否有任何方法可以实现这一目标?我需要以确保文档在被前一个文档更新之前不会被另一个读取器从池中提取出来。我基本上是在查看原子批处理更新。 谢谢!

回答

1

想必你正在做这样的事情来更新雕像:

db.docs.update({status:"arrived"},{$set:{status:"processing"}},{multi:true}) 

,然后用状态文件的加载:“处理”。

目前没有mongo咒语来更新多于一个但少于所有匹配的文件。您对所有文件使用{multi:true},或者您只标记一个文件。

鉴于此,您可以尝试使用非多重更新为每个读者进程标记具有唯一标识的到达文档。然后阅读文档进行处理。标记将用一个阅读器的唯一ID自动更新一个文档,从而避免阅读器之间的争用。

喜欢的东西:

db.docs.update({status:"arrived"},{$set:{status:"processing", readerId:<myid>}}) 

其中<myid>是价值的读取器进程发出此蒙戈更新的唯一ID。如果你使用findAndModify你可以找到原子和更新文档 db.docs.find({status:"processing", readerId:<myid>}}

+0

感谢您的答案,但我不认为这将解决问题。我的问题是,我希望批处理中的所有文档的状态可以自动更改并添加readerId似乎不处理该问题。 – Tazo 2013-05-02 05:07:06

+0

随着更新的全部或部分行为,标记时批量大小为1,或者所有新文档都将发送给一个阅读器。 – grogers 2013-05-02 14:55:59

+0

在http://docs.mongodb.org/manual/faq/concurrency/的第二次阅读中,我想说当多个线程使用相同的查询发出更新语句时,结果将不甚明了。这些线程将争夺文档,并且这将取决于什么线程在yield之后获得写入锁定。 mongo上有一个开放的问题来支持限制更新:https://jira.mongodb.org/browse/SERVER-1599。 – grogers 2013-05-02 15:23:04

0

然后读者可以加载文档。

如果

db.docs.findAndModify({ 
    query : {'status':'arrived' }, 
    sort: { dateTimeOfdoc:-1}, 
    update : { 'status':'processing','transactionId':12345}, 
    new : true}); 

虽然所有线程都为文档竞争,因为每个文件可以发现在原子操作修改,这意味着一旦一个线程有它,它不会被别人获取。

这不是你想要的一批文档,但是它能处理你的问题吗?