mongodb是原子查询更新吗?

bq3bfh9z  于 2023-03-17  发布在  Go
关注(0)|答案(2)|浏览(115)

mongodb写入和更新操作是原子的,如其docs中所述。
但是在使用查询时它也是原子的吗?
例如:

db.collection.update( { id : 1 , count : 0 } , { $inc : { count : 1 } } )

如果我在多线程环境中执行此操作,那么在某个时刻,id等于1的文档中count的值是否会大于1?

r1wp621o

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之前更新文档,则集合将包含:

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}存在的情况。

n7taea2i

n7taea2i2#

在文档中,未提及关于带有查询 * 的db.collection.update * 的原子性。
代替findAndModify()已经提到原子行为。
db.myCollection.findAndModify( { query: { ...},update: {....}})
参考查找和更新文档链接。

相关问题