我正在将我的应用程序从App Engine数据存储移植到MongoDB后端,我对"文档更新"的一致性有疑问我知道一个文档上的更新都是原子的和隔离的,但是有没有办法保证它们在不同的副本集之间"一致"呢?

在我们的应用程序中,许多用户可以(也将)通过在一次更新过程中插入几个嵌入式文档(对象)来同时更新一个文档.我们需要确保这些更新在所有副本中以逻辑一致的方式进行,即当一个用户将几个嵌入的文档"放入"父文档中时,在我们确保其他用户已阅读并收到第一个用户的更新之前,其他用户不能将其嵌入的文档放入父文档中.

因此,我所说的一致性是指,我们需要一种方法来确保,如果两个用户试图同时exactly次对一个文档执行更新,MongoDB只允许其中一个更新通过,并丢弃另一个(或至少防止两个都发生).我们不能在这里使用标准的"分片"解决方案,因为单个更新不只是增量或减量.

保证一个特定文档的一致性的最佳方法是什么?

推荐答案

MongoDB不提供主机复制或多版本并发.换句话说,写入always会进入副本集中的同一服务器.默认情况下,即使是从二级数据库读取也会被禁用,因此默认行为是一次只与一台服务器通信.因此,如果使用原子修饰符(如$inc, $push等),则无需担心安全模式下的结果不一致.

如果你不想局限于这些原子修饰符,那么按照dcrosta(和mongo docs)的建议进行比较和交换看起来是个好主意.然而,所有这些都与副本集或分片无关.

如果在数据库/ node 发生故障时还需要确保读取一致性,那么应该确保以安全模式向大多数服务器写入数据.

这两种方法的表现都是different if you allow unsafe reads:原子更新操作仍然有效(但可能会产生意外的结果),而比较和交换方法将失败.

Mongodb相关问答推荐

来自嵌套对象数组的 MongoDB 聚合

DB 中的引用对象在 GraphQL 查询中返回 null

根据聚合管道MongoDB Atlas触发器中的条件更新多个字段

如何在 Spring-Data-MongoDB 中使用 $facet、$addFields 和 $function

如何在mongodb中级联删除文档?

聚合/元素子文档作为 mongo 中的顶级文档

在一个变量上运行的 Node JS 中使用正则表达式的 Mongo 查询

如何检索 MongoDb 集合验证器规则?

如何在 MongoDB 中进行内部连接?

如何解决 ClassNotFoundException:com.mongodb.connection.BufferProvider?

从每个组中 Select 前 N 行

Ruby 按键值分组哈希

在 mongodb 聚合框架中执行 case-statement

填充mongoose后查找

Mongodb - 如何在多个字段中查找字符串?

使用 $in 进行不区分大小写的搜索

如何使用 mongoose 连接到 mongoDB Atlas

判断字段是否存在于数组的子文档中

验证 MongoCredential 的异常和未分类的 Mongo Db 异常

mongoosefind()不返回结果