【问题标题】:Is it possible to have atomic batch updates in MongoDB?是否可以在 MongoDB 中进行原子批量更新?
【发布时间】:2013-04-26 03:35:31
【问题描述】:

我在当前项目中遇到了 mongo 更新问题。我们在 MongoDB 中维护了一个文档池。读取器进程从该池中获取一批文档。为了确保不会再次从数据库中获取文档,与每个文档关联的状态都会更改(例如,从到达到处理中)。

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

【问题讨论】:

    标签: mongodb atomic


    【解决方案1】:

    大概你正在做这样的事情来更新雕像:

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

    随后加载状态为“处理中”的文档。

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

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

    类似:

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

    其中&lt;myid&gt; 是发布此 mongo 更新的读取器进程的唯一 id 值。

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

    【讨论】:

    • 感谢您的回答,但我认为这不会解决问题。我的问题是我希望批量更改所有文档的状态并且添加 readerId 似乎无法处理那个问题。
    • 通过更新的一种或全部行为,您要么在标记时批量大小为 1,要么所有新文档都将发送给一个阅读器。
    • 在第二次阅读docs.mongodb.org/manual/faq/concurrency 时,我会说,当多个线程发出具有相同查询的更新语句时,结果会是什么完全不清楚。线程将竞争文档,这完全取决于在产生后哪个线程获得写锁。 mongo 上有一个未解决的问题,以支持有限制的更新:jira.mongodb.org/browse/SERVER-1599
    【解决方案2】:

    如果您使用findAndModify,您可以自动查找和更新文档。

    如果你

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

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

    这不是您想要的一批文档,但它是否解决了您的问题?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 2011-05-25
      • 2014-01-27
      • 2017-07-12
      相关资源
      最近更新 更多