这意味着隔离写操作不提供“全有或全无”原子性

时间:2016-12-27 07:58:25

标签: mongodb

我正在使用Mongodb和$ isolate运算符文档进行交易,提到

  

隔离写操作不提供“全有或全无”   原子

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

中的

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

1 个答案:

答案 0 :(得分:1)

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

例如,假设一个带有3个文档的集合虚拟:{a:1}, {a:3}, {a:5}, {a:6}并且a上有唯一索引:

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已被弃用并且已替换为更合适的名称{ {1}}