防止两个微服务实例读取同一个文档。

问题描述 投票:0回答:1

我有两个相同的微服务实例在运行。这些微服务使用reactivemongo库引用一个mongodb集合。这个mongodb集合模拟了一个队列。因此,每个微服务都会在队列中选取最新的项目,然后进行处理(不能改变这种设计,因为这是公司提出的,他们不想改变)。

我担心两个实例在队列中选取(即读取)同一个元素,然后开始处理它。他们说,由于mongodb的原子性属性,这种情况不可能发生。但在我看来,原子性操作意味着数据库操作要么完全发生,要么根本不发生。那么在我描述的这种情况下,这有什么帮助呢?我觉得没有。

他们还说,每个实例当它试图读取一个文档进行处理时,如果它找到一个文档,那么它就会将状态从Todo更新为In-Progress。他们说,这意味着,如果另一个实例出现,它将不会接收到相同的文档,因为状态不再是Todo。

他们的意思似乎是说,在更新文档状态从ToDo到In-Progress的原子操作过程中,由于原子性的原因,即使更新还没有发生,其他实例也不能读取同一行。mongodb是这样工作的吗?

mongodb microservices reactivemongo
1个回答
0
投票

Mongo DB支持文档级锁定,所以你基本上可以锁定一行,这样其他服务就不会把它取走。参考文档是 此处.

另一种解决方案是使用操作 查找和修改(),可以让你原子地修改一个文档。这虽然慢了点,但也是个好办法。所以你可以使用findAndModify标记正在进行中的文档,这样其他服务就不会发现。它将会工作,因为你的查找条件将只有to-do。

例如

var doc = db.runCommand({
              "findAndModify" : "COLLECTION_NAME",
              "query" : {"_id": "ID_DOCUMENT", "status" : "TO_DO"},
              "update" : {"$set" : {"status" : "IN_PROGRESS"} }
}).value
© www.soinside.com 2019 - 2024. All rights reserved.