如何使用MongoDB和两阶段提交解决多个并发写入?

时间:2012-09-29 08:33:09

标签: mongodb concurrency

我已经为MongoDB实现了两阶段提交,如MongoDB的documentation中所述。基本上,这很好。它特别容易,因为我所关心的是插入新文档,我从不更新它们。

然而,我担心一个特殊情况,我不知道如何解决这个问题。所以任何帮助都会受到赞赏。

给定:包含具有以下结构的文档的集合:

id: ...,
subId: ...
payload: {
  ...
}

可能有多个文档具有相同的id,但具有相同id的所有文档都会增加subId。所以,你有类似的东西:

  • 1 - 1
  • 1 - 2
  • 2 - 1
  • 3 - 1
  • 3 - 2
  • 3 - 3

每个插入只处理一个id,但可能提供多个文档。因此,这意味着可能会有包含文档3 - 43 - 5的插入内容,但绝不会插入包含文档3 - 44 - 1的内容。

idsubId字段由客户端插入数据计算。

插入多个文档时,此插件由2PC覆盖。所以要么所有文件都已提交,要么都没有。

问题现在出现在2PC的第二阶段。由于我不希望其他客户端能够读取未提交的数据,因此每个文档中都有一个标志,告诉我文档是否已经提交。一旦所有文件都已写入并且交易已设置为“已完成”,作为最后一步,文档将被标记为已提交。

所以现在如果我尝试插入3 - 43 - 5会发生什么,写入,事务完成,3 - 4被标记为已提交,并且在{{1}之前标记为已提交,另一个客户端读取标识为3 - 5的所有文档,将subId 3视为最高文档,创建一个包含4的新文档并插入它?

然后提交失败,我从两个事务中混合了版本号。

如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

哦,忘了它......“我写的时候会看到它”的典型情况。我描述的场景没有问题,因为3 - 5已经由第一个事务写入,它只是没有提交。因为id - subId上存在唯一的索引约束,另一个事务不会干扰。

问题解决了。