【发布时间】:2015-04-23 06:12:49
【问题描述】:
如果我有一个环境,其中同一客户端的多个实例连接到 MongoDB 服务器,并且我想要一个简单的锁定机制来确保短时间内单个客户端访问,我可以安全地使用自己的锁定对象吗?
假设我有一个带有 lockState 的对象,可以“锁定”或“解锁”,计划是每个人在做“事情”之前检查它是否“解锁”。要锁定系统,我说:
db.collection.update( { "lockState": "unlocked" }, { "lockState": "locked" })
(又名UPDATE lockObj SET lockState = 'locked' WHERE lockState = 'unlocked')
如果两个客户端同时尝试锁定系统,是否有可能两个客户端最终都认为他们“拥有锁定”?
- 两个客户端都通过更新的查询参数找到记录
- 客户端 1 更新记录(这是一个原子操作)
- 更新返回成功
- 客户端 2 更新文档(在客户端 1 修改之前已经找到它)
- 更新返回成功
我意识到这可能是一个非常人为的案例,很难重现,但有可能还是 mongo 以某种方式使客户端 2 的更新失败?
替代方法
使用插入而不是更新。 insert 是原子的,如果文档已经存在就会失败。
锁定系统:db.locks.insert({someId: 27, state: “locked”})。
如果插入成功 - 我已经获得了锁,并且由于更新是原子的,所以没有其他人可以拥有它。
如果插入失败 - 其他人必须拥有锁。
【问题讨论】:
-
等等,你是不是故意将你的数据库从多线程向下钻取到单线程?这就是第一段所说的......
标签: mongodb