【问题标题】:Prevent Two Microservice Instances Reading The Same Document防止两个微服务实例读取同一个文档
【发布时间】:2020-05-11 15:46:50
【问题描述】:

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

我担心两个实例会选择(即读取)队列中的相同元素,然后开始对其进行处理。他们说由于 mongodb 的原子性特性,这不会发生。但对我来说,原子操作意味着数据库操作要么完全发生,要么根本不发生。那么在我所描述的这种情况下,这将有什么帮助呢?我认为不会。

他们还说,每个实例在尝试读取文档进行处理时,如果找到一个,就会将状态从 Todo 更新为 In-Progress。他们说这意味着如果另一个实例出现,它不会选择同一个文档,因为状态不再在 Todo 中。

似乎他们的意思是,在将文档状态从 ToDo 更新为 In-Progress 的原子操作期间,即使由于原子性而尚未发生更新,其他实例也无法读取同一行。 mongodb是这样工作的吗?

【问题讨论】:

    标签: mongodb microservices


    【解决方案1】:

    Mongo DB 支持文档级锁定,因此您基本上可以锁定一行,这样其他服务就不会获取它。参考文档是here

    另一个解决方案可能是使用操作findAndModify(),它使您能够以原子方式修改文档。这有点慢,但可以解决问题。因此,您可以使用 findAndModify 标记正在进行的文档,以便其他服务不会接听。它会起作用,因为您的查找条件只有 TO-DO。

    例如

    var doc = db.runCommand({
                  "findAndModify" : "COLLECTION_NAME",
                  "query" : {"_id": "ID_DOCUMENT", "status" : "TO_DO"},
                  "update" : {"$set" : {"status" : "IN_PROGRESS"} }
    }).value
    

    【讨论】:

    • 所以你是说mongodb的原子语义是一旦一个线程找到了文档就没有其他线程可以锁定它?
    • 是的,在这里检查并发控制-docs.mongodb.com/manual/core/write-operations-atomicity
    • 如果您同意这篇文章,请告诉我。
    • 有类似findAndModifyMany()的操作吗?在这种情况下有什么解决方案。多个实例需要读取多个不同的文档,我需要确保没有重复的文档。
    猜你喜欢
    • 1970-01-01
    • 2021-04-03
    • 2018-11-23
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 2016-08-07
    相关资源
    最近更新 更多