【问题标题】:MongoDB auto-increment field and read orderMongoDB自增字段和读取顺序
【发布时间】:2021-09-13 16:08:25
【问题描述】:

我有一个多实例服务,每秒将大约 100 个文档写入 Mongo 数据库。

现在我正在开发一个应用程序,该应用程序必须按照插入的顺序处理这些文档。

我坚持这种严格的顺序处理顺序的要求。

我想避免使用任何队列消息系统,因此最简单的解决方案是为每个文档添加一个唯一的自动增量字段,然后调用find() 方法来获取一些具有该字段值的文档大于最后处理的文档。 我已经阅读了this official article 关于在 Mongo 中创建自增字段的内容,但是这种方法是否保证了写入顺序?

假设有这样的操作序列按指定的顺序发生,但中间没有延迟(自动增量字段的初始值 = 0):

  1. 服务的实例 #1 调用 db.collection.insertOne() 并带有一个巨大的复杂文档 #1,这可能会使 Mongo 需要一些时间来处理它。
  2. 实例 #2 调用 insertOne() 并使用一个小的简单文档 #2。
  3. 我的应用在同一个集合上执行find()

步骤 3 中的 find() 方法是否有可能只返回文档 #2,其自动增量字段的值 = 2,片刻之后,文档 #1 最终将被写入数据库值 = 1?

基本上,我担心自动增量字段的值可能会在相应的文档可供读取之前被碰撞,因此下一个文档可能会在第一个文档之前对客户端可见,尽管具有更高的字段值。

更新:

以下是我认为可能发生的事情的时间表:

【问题讨论】:

  • 文档#1 和#2 都将具有相同的_id,这是在这些文档中的任何一个存在之前计算的。无论哪个文档最终被插入第二个都将失败索引唯一性约束并且不会被插入。所以你不能让它们都存在于数据库中。
  • 我猜你误会了我。我没有使用标准的_id生成算法,我想使用this page的自动增量实现。

标签: mongodb auto-increment


【解决方案1】:

如果 _id=1 的文档 #1 已写入数据库,则您的文档 #2 只能具有 _id=2。

因此,您所描述的情况不会发生 - 如果数据库中还没有文档 #1,您就不能在客户端构建带有 _id=2 的文档 #2。文档 #1 和 #2 的持久性操作,如果它们具有不同的 _id 值,则必须是顺序的(不重叠)。

【讨论】:

  • 嗯,问题是 - 文档 #1 会在文档 #2 之前写入数据库吗?获取一个新的 _id 和持久化一个文档基本上是两个操作,对吧?那么,Mongo 中是否可以保证文档 #1 的 insertOne() 操作将在文档 #2 之前将其持久化到数据库中,即使文档 #1 比文档 #2 更大并且需要更多时间来处理?
  • 您对操作顺序感到困惑。将它们写在一张纸上,从数据库中分离 id 检索,在客户端构建文档,启动每个文档的写入操作。
【解决方案2】:

我发现我的问题中描述的情况,即后来插入的文档 #2 在文档 #1 之前变得可见时,是不可能的,至少对于独立的 Mongo 实例是不可能的。

MongoDB 在这种情况下保证单调写入:

https://docs.mongodb.com/manual/core/read-isolation-consistency-recency/#monotonic-writes

【讨论】:

    猜你喜欢
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多