【问题标题】:How doest Trello store generated actions from updates to other documents (boards, cards) in MongoDB without atomic transactions?Trello 如何在没有原子事务的情况下将生成的操作从更新到 MongoDB 中的其他文档(板、卡)存储?
【发布时间】:2019-09-04 15:30:34
【问题描述】:

我正在开发一个将使用 NoSQL 文档数据库(如 MongoDB)的单页 Web 应用程序,并且我想在对我的实体进行更改时生成事件。

由于这些数据库中的大多数仅支持文档级别的事务(MongoDB 刚刚添加了 ASIC 支持),因此没有好的方法可以将更改存储在一个文档中,然后将这些更改中的事件存储到其他文档。

例如,假设我有一个集合“事件”和一个集合“卡片”,就像 Trello 一样。当我对“卡片”集合中的卡片描述进行更改时,应该会生成一个事件“CardDescriptionChanged”。

问题是,如果在保存对“卡片”集合的更改和在“事件”集合中添加事件之间发生崩溃或一些错误,则此事件将不会持续存在,我不希望这样。

我已经对此问题进行了一些研究,大多数人会建议可以使用以下几种方法之一:

  1. 不要使用 MongoDB,而是使用 SQL 数据库(我不想那样)

  2. 使用事件溯源。 (这引入了复杂性,我想在某个时候清除旧事件,所以我不想保存所有事件。我现在可以使用快照并从快照点删除旧事件,但这有一个复杂性解决方案)

  3. 由于这种性质的错误可能不会经常发生,请忽略它们并冒着发生无法保存的事件的风险(我也不希望这样)

  4. 使用事件/命令/动作处理器。存储命令/动作,如“ChangeCardDescription”,并使用处理器来处理它们并更新实体。

我已经考虑过选项 4,但出现了几个问题:

  • 如何管理并发?

我可以将同一实体(如卡片或棋盘)的所有命令排队,并确保它们按顺序处理,而不同实体(不同卡片)的事件可以并行处理。然后我可以将处理后的命令用作事件。这里的一个问题是对实体的更改可能会生成多个事件,这些事件可能不对应于单个命令。我必须将所有用户操作分解为非常细粒度的命令,以便我可以将它们转换为事件。

  • 错误报告和错误处理。

如果此过程是异步的,我必须管理向客户端报告错误。而且我还必须删除或标记失败的命令。

  • 我仍然无法将命令标记为已处理,因为没有事务。我知道我必须使命令处理具有幂等性才能解决此问题。

由于 Trello 使用 MongoDB 并生成操作('DeleteCardAction'、'CreateCardAction')并更改实体(卡片、板..),我想知道他们如何解决这个问题?

【问题讨论】:

    标签: mongodb event-sourcing trello


    【解决方案1】:

    创建一个名为FutureUpdates 的新集合。将计划更新写入FutureUpdates 集合,并使用一个文档定义您计划对卡片进行的更改以及您计划生成的事件。此插入将是原子的。

    现在从FutureUpdates 集合中获取[ChangeStream][1],这将为您提供需要进行的更新流。从更改流中获取每个文档并应用更新。最后,更新FutureUpdates 中的文档以将其标记为完成。同样,此更新将是原子的。

    当您将更新应用到事件和卡片时,请确保在 FutureUpdates 中包含用于创建更新的文档的 objectID。

    现在,如果在FutureUpdates 中插入更新后程序崩溃,您可以检查事件和卡片集合中是否存在包含更新的 objectID 的记录。如果它们不存在,那么您可以重新应用丢失的更新。

    如果已应用更新但FutureUpdate 文档未标记为完成,我们可以在恢复期间更新它以完成该过程。

    实际上,您正在为FutureUpdates 中的每个更改自动更新文档以跟踪进度。更新完成后,您可以存档旧文档或删除它们。

    【讨论】:

    • 感谢您的建议。我正在考虑做这样的事情。我正在考虑使用诸如 CQRS 系统之类的东西,其中有多个模型,但会丢弃线模型的更改。我想知道是否还有其他比这更简单的解决方案,我可能会错过。由于 Trello 解决了它(而且我喜欢他们的系统),我想知道他们是如何做到的 :)
    猜你喜欢
    • 2022-01-22
    • 2020-10-18
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2017-01-23
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多