【问题标题】:Mongodb retryable-writesMongodb 可重试写入
【发布时间】:2018-07-25 10:14:16
【问题描述】:

如果我在 mongodb 中启用 retryable-writes 并执行以下插入

await db.collection('inventory').insertOne({
  item: 'canvas',
  qty: 100,
  tags: ['cotton'],
  size: { h: 28, w: 35.5, uom: 'cm' }
});

是否有可能在某些情况下,驱动程序插入了两条相同的记录

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    可重试写入旨在为受支持的存储引擎和可重试操作提供“一次且仅一次”语义,并带有特定的prerequisites。有许多保护措施旨在防止可重试写入发生多次。

    话虽如此,在Retryable Writes documentation page

    如果客户端应用程序在发出写入操作后暂时无响应超过 localLogicalSessionTimeoutMinutes,则当客户端应用程序开始响应(无需重新启动)时,可能会重试并再次应用写入操作。

    这需要一个完美的厄运风暴在正确的时间以正确的顺序发生,跨越 30 多分钟,以便可重试写入发生两次:

    1. 客户端向服务器发送可重试的写入请求。
    2. 服务器应用写入,但出现问题阻止确认到达客户端。
    3. 客户端应用程序挂起超过localLogicalSessionTimeoutMinutes(默认为 30 分钟)。
    4. 30 多分钟后,应用程序尝试从中断处继续,认为它没有收到写入确认,然后重试写入。

    为了实现这一点:

    • 应用程序挂起必须发生在恰好的时间窗口,其中:
      • 写入发生在服务器中。
      • 确认不能到达客户端,例如迷路了。
    • 应用程序可以在 30 多分钟后从中断处继续,而不会出错。

    这是一个极不可能发生的事件链。

    但是,如果您担心自己会遭遇这一系列不幸事件,您可以:

    • 插入带有特定_id 的文档。第二次插入将失败,因为 _id 在集合中必须是唯一的。
    • 对更新使用幂等操作,例如$set 而不是$inc

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 2021-02-06
      • 2018-10-21
      • 1970-01-01
      • 2021-09-12
      • 1970-01-01
      • 2020-07-22
      • 2020-04-09
      相关资源
      最近更新 更多