mongodb写入和更新操作是原子的,如其docs中所述。但是在使用查询时它也是原子的吗?例如:
mongodb
db.collection.update( { id : 1 , count : 0 } , { $inc : { count : 1 } } )
如果我在多线程环境中执行此操作,那么在某个时刻,id等于1的文档中count的值是否会大于1?
id
count
r1wp621o1#
对单个文档的任何修改都是原子的。以您的示例为例,假设有两个线程尝试使用同一个查询更新该文档:
Thread A: db.collection.update({_id: 1, count: 0}, {$inc: {count: 1}}) Thread B: db.collection.update({_id: 1, count: 0}, {$inc: {count: 1}})
与包含文档的集合:
collection: {_id: 1, count: 0}
如果线程A设法在线程B之前更新文档,则集合将包含:
A
B
collection: {_id: 1, count: 1}
线程B将搜索与_id:1, count:0匹配的文档,但由于该文档已被线程A修改,因此线程B中的更新将不会继续(因为就线程B而言,该文档不再“存在”)。换句话说,线程A将返回nMatched: 1, nModified: 1,线程B将返回nMatched: 0, nModified: 0。为了具体回答您的问题,将不存在文档{_id: 1, count: 2}存在的情况。
_id:1, count:0
nMatched: 1, nModified: 1
nMatched: 0, nModified: 0
{_id: 1, count: 2}
n7taea2i2#
在文档中,未提及关于带有查询 * 的db.collection.update * 的原子性。代替findAndModify()已经提到原子行为。db.myCollection.findAndModify( { query: { ...},update: {....}})参考查找和更新文档链接。
db.collection.update
findAndModify()
db.myCollection.findAndModify( { query: { ...},update: {....}})
2条答案
按热度按时间r1wp621o1#
对单个文档的任何修改都是原子的。
以您的示例为例,假设有两个线程尝试使用同一个查询更新该文档:
与包含文档的集合:
如果线程
A
设法在线程B
之前更新文档,则集合将包含:线程
B
将搜索与_id:1, count:0
匹配的文档,但由于该文档已被线程A
修改,因此线程B
中的更新将不会继续(因为就线程B
而言,该文档不再“存在”)。换句话说,线程
A
将返回nMatched: 1, nModified: 1
,线程B
将返回nMatched: 0, nModified: 0
。为了具体回答您的问题,将不存在文档
{_id: 1, count: 2}
存在的情况。n7taea2i2#
在文档中,未提及关于带有查询 * 的
db.collection.update
* 的原子性。代替
findAndModify()
已经提到原子行为。db.myCollection.findAndModify( { query: { ...},update: {....}})
参考查找和更新文档链接。