是否可以在MongoDB中进行原子批量更新?

时间:2013-05-02 03:42:50

标签: mongodb atomicity

我在当前项目中遇到mongo更新问题。我们在MongoDB中维护了一个文档池。读取器进程从此池中提取一批文档。为了确保不再提取DB中的文档,将更改与每个文档关联的状态(例如,从“到达”到“处理”)。

我们正在考虑扩展并让多个读取器进程获取不同的批次。但是,根据我的理解,mongo更新在批处理上不是原子的。我有什么办法可以实现这个目标吗?我需要确保在前一个文档更新之前,不同的阅读器不会从池中拾取文档。我基本上是在查看原子批量更新。 谢谢!

2 个答案:

答案 0 :(得分:1)

据推测,你正在做这样的事情来更新雕像:

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

然后加载状态为“processing”的文档。

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

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

类似的东西:

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

其中<myid>是发出此mongo更新的读者进程的唯一ID值。

然后读者可以加载文档: db.docs.find({status:"processing", readerId:<myid>}}

答案 1 :(得分:0)

如果您使用findAndModify,则可以原子方式查找和更新文档。

如果你

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

虽然所有线程都在竞争文档,因为每个文档都可以在原子操作中找到并修改,这意味着一旦线程拥有它,它就不会被其他人获取。

这不是您想要的一批文档,但是它是否可以处理您的问题?