【发布时间】:2017-05-11 12:14:24
【问题描述】:
我正在使用 Mongodb 进行交易,并且在 $isolate 操作员文档中提到了
独立的写操作不提供“全有或全无” 原子性
在https://docs.mongodb.com/manual/core/write-operations-atomicity/
这很令人困惑,那么 $isolate 运算符的全部目的是什么。有人可以解释一下吗。在此先感谢。
【问题讨论】:
标签: mongodb
我正在使用 Mongodb 进行交易,并且在 $isolate 操作员文档中提到了
独立的写操作不提供“全有或全无” 原子性
在https://docs.mongodb.com/manual/core/write-operations-atomicity/
这很令人困惑,那么 $isolate 运算符的全部目的是什么。有人可以解释一下吗。在此先感谢。
【问题讨论】:
标签: mongodb
$isolated 影响隔离,而不是原子性。也就是说,一旦“隔离”操作修改了第一个文档,就会建立锁定。从那一刻开始,直到操作完成并释放锁,任何其他客户端都不会看到修改,其他写操作不会影响受影响的文档
例如,假设一个集合 dummy 包含 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 已被弃用,并已被更合适的名称 $isolated 取代
【讨论】: