mongodb - 隔离写操作不提供 “all-or-nothing”原子性是什么意思

标签 mongodb

我正在使用 Mongodb 进行事务处理,并且在 $isolate 运算符(operator)文档中提到了

An isolated write operation does not provide “all-or-nothing” atomicity

https://docs.mongodb.com/manual/core/write-operations-atomicity/

令人困惑的是,$isolate 运算符的全部目的是什么。有人可以解释一下吗?提前致谢。

最佳答案

$isolated 影响隔离性,而不是原子性。也就是说,一旦“隔离”操作修改了第一个文档,就会建立锁定。从那一刻起,直到操作完成并释放锁,任何其他客户端都不会看到修改,其他写入操作也不会影响受影响的文档

例如,假设一个集合虚拟包含 3 个文档:{a:1}、{a:3}、{a:5}、{a:6} 且具有唯一索引一个:

db.dummy.createIndex({a:1},{unique:true})

以及以下更新:

db.dummy.update(
    { $isolated : 1 },
    { $inc : { a : 1 } },
    { multi: true }
)

产生:

 db.dummy.find({},{_id:0})
{ "a" : 2 }  // 2 --> was 1
{ "a" : 4 }  // 4 --> was 3
{ "a" : 5 }  // 5 --> not changed; produced a duplicated key error
{ "a" : 6 }  // 6 --> not changed; operation aborted before reaching this document

尝试增加 5 时操作已中断,因为它导致重复键错误,并且 5 和 6 均不受影响。这里不存在原子性,因为 a:2,a:4 中的更改没有回滚。

隔离确保没有客户端能够看到处于这种中间状态的集合:

 db.dummy.find({},{_id:0})
{ "a" : 2 }  // 1 --> 2
{ "a" : 3 }  // 3 --> still not modified
{ "a" : 5 }  // 5 --> still not modified
{ "a" : 6 }  // 6 --> still not modified

也就是说,其他客户端无法看到“中间”的操作;一旦开始,他们将在最后看到所有的变化。

这里非常令人困惑的一点是,$isolated 在 2.2 版本之前被称为 $atomic,这确实令人困惑,但现在 $atomic已弃用并已替换为更合适的名称 $isolated

关于mongodb - 隔离写操作不提供 “all-or-nothing”原子性是什么意思,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41341266/

相关文章:

c++ - 使用 CMake 生成 Visual Studio 2017 项目

javascript - 为什么找不到带有 '$all' 修饰符的文档?

java - Mongodb 查询列表<Map<String, Map<String, String>>>

mongodb - 如何确定操作导致 MongoDB 服务器上的 getMore 操作

php - MongoDB 更新嵌套数组

MongoDB 查询连接两个集合

javascript - mongoose.Promise 和 promisifyAll 有什么区别?

mongodb - 如何使用Dart在mongoDb上获得执行时间?

php - MongoDB 选择排序问题

c++ - 在 c++ r3.0.2 驱动程序中使用连接池连接到 mongodb 拷贝集的正确方法是什么?