MongoDB中findAndModify()的并发处理问题
MongoDB findAndModify() 并发执行的行为解析
嘿,这个问题问到点子上了,咱们一步步理清楚:
首先给出明确结论:第二个进程确实会在第一个进程完成后执行修改操作,而且它会基于第一个进程更新后的最新数据来执行。
为什么会这样?核心在于findAndModify()的原子性特性:
- 这个方法的查询和修改操作是绑定在一起的原子步骤,MongoDB会保证整个操作要么完全执行,要么完全不执行。
- 当第一个进程获取到文档的写锁后,它会完成完整的查询+修改流程,直到释放锁,第二个进程才能拿到锁进行操作。
- 第二个进程执行时,会重新执行查询条件——这时候它看到的是第一个进程修改后的文档状态,而不是最初的原始数据,之后才会基于这个最新状态执行修改。
举个实际场景的例子更直观:
假设我们有个统计点击量的文档:{ _id: "page1", clicks: 0 },两个进程同时调用:
db.collection.findAndModify({ query: { _id: "page1" }, update: { $inc: { clicks: 1 } } })
- 进程A先抢占到锁,查询到
clicks为0,把它更新为1,然后释放锁。 - 进程B拿到锁后,查询到的
clicks已经是1了,接着把它更新为2。最终文档的clicks值是2,而不是两个操作都基于原始的0修改导致结果为1——这也体现了findAndModify()在并发场景下的安全性。
如果你的业务逻辑必须基于某个特定的原始状态做修改,那可能需要额外引入乐观锁机制(比如给文档加个version字段,更新时带上版本号校验),但默认情况下,findAndModify()的并发执行就是上述的行为,保证每个操作都基于最新的文档状态。
内容的提问来源于stack exchange,提问作者user994165
相关产品推荐
相关产品推荐

