如果我有一个环境,同一客户端的多个实例连接到MongoDB服务器,并且我想要一个简单的锁定机制来确保短时间内单个客户端访问,我可以安全地使用自己的锁定对象吗?
假设我有一个具有lockState的对象可以被“锁定”或“解锁”,并且计划是每个人在执行“东西”之前检查它是否已“解锁”。为了锁定系统,我说:
db.collection.update( { "lockState": "unlocked" }, { "lockState": "locked" })
(又名UPDATE lockObj SET lockState = 'locked' WHERE lockState = 'unlocked'
)
如果两个客户端同时尝试锁定系统,那么两个客户端是否可能最终认为他们“有锁”?
我意识到这可能是一个非常难以重现的非常人为的案例,但它是否可能或者mongo以某种方式使客户2的更新失败?
替代方法
使用insert而不是update。 insert是原子的,如果文档已经存在则会失败。
锁定系统:db.locks.insert({someId: 27, state: “locked”})
。
如果插入成功 - 我得到了锁,因为更新是原子的,没有其他人可以拥有它。
如果插入失败 - 其他人必须拥有锁。
答案 0 :(得分:0)
如果两个客户端同时尝试锁定系统,那么两个客户端是否有可能最终认为他们“有锁”?
不,一次只有一个客户端写入锁定空间(全局,数据库,集合或文档,具体取决于您的版本和配置),并且该锁定空间上的操作是顺序的和一个或另一个(读取或写入,并非两者都是每个文档,以便其他连接不会错误地在中间状态中拾取文档并认为它没有被其他客户端锁定。
单个文档上的所有操作都是原子操作,无论是更新还是插入。