MongoDB updateOne原子性及相关执行机制技术咨询
MongoDB updateOne 原子性与锁机制问题
给定操作:
db.collection.updateOne( { _id: "unique_object_id", field_a: 5 }, { $inc: { field_a: 1 } } )
假设集合中仅有一个文档的field_a字段值为5,即仅有一个文档匹配上述查询条件。
问题1:若同时执行两次上述updateOne查询,该文档的field_a字段最终值是否可能为7?
不可能,最终值只会是6。
原因:updateOne结合$inc的更新是原子操作,且MongoDB在执行写操作时,会在获取文档锁后重新校验匹配条件。第一个操作匹配文档并将field_a自增为6,第二个操作等待锁释放后,重新检查条件时会发现field_a已变为6,不再满足field_a:5的查询条件,因此不会执行更新。
问题2:锁定机制是否在匹配文档之后触发?即两个查询均会找到并确定该文档为待更新对象(因二者均未完成更新),其中一个锁定文档并将field_a自增为6,解锁后另一个查询再将其自增为7?
锁定确实在找到匹配文档之后、执行更新之前触发,但后续不会出现第二个操作再自增的情况。
具体流程:
- 两个操作都会先查询到
field_a=5的文档(默认读隔离级别为读已提交,若第一个操作未提交,第二个操作仍能看到原始值); - 第一个操作先获取文档锁,执行自增更新为6,提交后释放锁;
- 第二个操作等待锁释放后,会重新校验文档是否匹配查询条件,此时
field_a已是6,不满足条件,因此不会执行更新。
问题3:承接问题2,第二个查询是否会在第一个查询释放锁后重新评估匹配条件?
会。MongoDB写操作在获取文档锁后、执行更新前,会重新检查文档是否仍满足查询条件,避免等待锁期间文档被其他操作修改,导致执行不符合原始查询意图的更新。
问题4:findOneAndUpdate在该场景及原子性方面是否遵循与updateOne相同的规则与策略?
是的。findOneAndUpdate和updateOne在单个文档更新的原子性、锁机制、匹配条件重校验规则上完全一致。两者核心区别仅在于findOneAndUpdate会返回更新前(或更新后,取决于returnNewDocument参数)的文档,而updateOne仅返回更新结果的统计信息(如匹配数、修改数)。
内容的提问来源于stack exchange,提问作者Bear Bile Farming is Torture
相关产品推荐
相关产品推荐

