【问题标题】:is the search component of mongodb update also atomic?mongodb更新的搜索组件也是原子的吗?
【发布时间】:2012-06-13 00:19:51
【问题描述】:

MongoDB Update documentation 中,他们谈到更新操作符是原子的。如果以下查询在同一时刻被调用五次,并且 Zugwalt 的声誉从零开始,我希望最终声誉为 5:

db.rep.update({_id: "Zugwalt"}, {$inc: {reputation: 1}});

但是如果更新查询是这样呢?

db.rep.update({_id: "Zugwalt", reputation: {$lte: 3}}, {$inc: {reputation: 1}});

声望是否总是只更新 3 次,还是有一些奇怪的竞争条件可以更新更多?

我的特殊情况是使用活跃用户“声明文档”。我执行类似于以下的查询:

db.myCollection.update({_id: "doc_id", activeUser: {$exists: false}}, {$set: {activeUser: "Zugwalt"}});

理想情况下,如果此查询在同一实例中多次触发,则只有一次更新会导致集合被修改。但是,如果搜索组件在更新时不是原子的,我可以看到一个竞争条件,它首先更新为将 activeUser 设置为一个用户,然后立即设置为另一个用户。

旁注:findAndModify 命令具有这种原子性似乎更清楚,但是我不想使用它,因为在我们使用我们的 node-js 驱动程序进行的经验测试中,在重负载下总体上看起来要慢得多.

【问题讨论】:

    标签: mongodb atomic


    【解决方案1】:

    在 MongoDB 中,更新是原子的。如果您不需要取回文档,则无需使用 findAndModify。

    在您给出的场景中,预期的事情将会发生 - 在第一种情况下,声誉最终会是 5,在第二种情况下会是 4。

    在您的情况下,只有一个更新会成功设置 activeUser。

    这是一个link,它讨论了 MongoDB 中的原子操作。

    【讨论】:

    • 现在,如果您需要取回您修改过的文档,那么您需要使用 findAndModify。
    • 嘿Asya,你怎么知道的?有没有可以提供的链接?同样根据我们的经验,我们发现使用更新,然后发现比 findAndModify 快得多!也许是因为我们使用了具有单个事件循环的 nodejs,所以能够在更新和查找之间有机会执行其他事情是件好事。
    • 我会将链接添加到答案 - 这里是示例 2:mongodb.org/display/DOCS/Atomic+operation+examples
    【解决方案2】:

    对于这种情况,您应该使用findAndModify。它是完全原子的。

    类似这样的:

    db.runCommand({findAndModify: 'myCollection',
                   query: {_id: "doc_id", activeUser: {$exists: false}},
                   update: {$set: {activeUser: "Zugwalt"}}})
    

    【讨论】:

    • 正如我在旁注中指出的那样,我意识到 findAndModify 是,但是我想知道更新是否是完全原子的,以及我们不需要修改后的对象。
    • 如果将其与安全模式下的更新进行比较会怎样?速度是否可比(相同)?
    • 我们在安全模式下进行更新,它们仍然比 findAndModify 快得多(这让我怀疑它是否是原子的)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多