Mongodb重试写入

时间:2018-07-24 06:04:47

标签: mongodb

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

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

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

1 个答案:

答案 0 :(得分:4)

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

话虽如此,在Retryable Writes documentation page中:

  

如果在发出写操作后客户端应用程序暂时对多于localLogicalSessionTimeoutMinutes的响应无响应,则有可能当客户端应用程序开始响应(不重新启动)时,可以重试并再次应用写操作。

这需要一次完全正确的时间,以正确的顺序(至少30分钟)发生一次不幸的风暴,以使可重试的写入发生两次:

  1. 客户端将可重试的写入请求发送到服务器。
  2. 服务器执行写操作,但是问题阻止了确认到达客户端。
  3. 客户端应用程序的挂起时间超过localLogicalSessionTimeoutMinutes(默认值为30分钟)。
  4. 超过30分钟后,该应用程序尝试从上次中断的地方接起,认为它尚未收到写入确认,然后重试写入。

要做到这一点:

  • 应用程序挂起必须必须在恰好的时间范围内发生:
    • 写入发生在服务器中。
    • 确认不得到达客户,例如迷路了。
  • 该应用程序可以在30分钟以上没有中断的情况下从其中断处继续取回。

这是极不可能的事件链。

但是,如果您担心会遇到这一系列不幸的事件,则可以:

  • 使用特定的_id插入文档。由于_id在集合中必须唯一,因此第二次插入将失败。
  • 使用幂等操作进行更新,例如使用$set代替$inc