【问题标题】:How to validate the event flow in DDD - Event sourcing?如何验证 DDD 中的事件流 - 事件溯源?
【发布时间】:2020-02-01 21:15:48
【问题描述】:

我正在构建一个 DDD/CQRS 事件溯源应用程序。 (.NET,EventStore)

我读了很多关于它的文章,尤其是著名的银行账户话题。

提醒一下,我们有以下事件序列:

  1. BankAccountCreated
  2. 已存款
  3. 画了
  4. ChangedOwner
  5. 已存款

但我从未找到解释如何验证事件序列的博客文章? 我的意思是,如果我在 BankAccountCreated 之前先收到 Deposited 事件会发生什么? 换句话说,我如何检查银行帐户是否已创建? 我如何知道流处于有效状态?

我必须调用读取模型吗?每次?在每个事件中?每个方法的聚合? 如果用户发送了两次并且 readmodel 还没有同步会发生什么?

我已经阅读了很多关于事件溯源的内容,可能还不够 ^^,但是我没有找到任何关于事件流一致性的信息。

在我的应用程序中,如果“第一个”事件 (ContactAdded) 不存在,我将无法应用事件。 这是否意味着我每次需要做某事时都必须调用 EventStore?

感谢您的帮助。

【问题讨论】:

    标签: .net-core domain-driven-design cqrs event-sourcing


    【解决方案1】:

    那里有很多。

    我如何知道流处于有效状态?

    每个流的每个事件都应该有一个单调递增的版本号。事件 1 应先于事件 2 等,每个流(聚合)。 EventStore 将通过应用乐观并发来确保这种级别的一致性。当您将事件写入事件存储时,您可以提供预期的流版本(例如最后写入的版本)。当您读取事件流时,您会获取最后一个版本号,并在将事件写入 EventStore 时将其传递。如果自上次阅读后事件流已经增长,则会引发并发错误。

    我必须调用读取模型吗?每次?在每个事件中?每个方法的聚合?

    这里有一些术语混淆。请记住事件与命令、读取与写入模型以及每个模型的用途。您显示来自 Read 模型的数据。您针对您的写入模型进行验证和处理。

    如果用户发送了两次并且 readmodel 还没有同步会发生什么?

    鉴于上面的乐观并发策略,您基本上获得了先入为主的策略。为了解决这个问题,您可以捕获并发错误并从头开始重新处理您的命令(从 EventStore 获取最新状态)。

    这是否意味着我每次需要做某事时都必须调用 EventStore?

    是的。在每个命令上,您将读取聚合和恢复状态的事件流。您可以使用快照作为优化,但概念保持不变。

    【讨论】:

    • 感谢您的回答,这证实了我最初的想法。
    【解决方案2】:

    如何验证 DDD 中的事件流 - 事件溯源? 我如何知道流处于有效状态?

    在领域驱动设计中,领域模型负责确保状态满足您的领域不变量。你可以把它想象成一个函数

    everythingWeKnowNow = domainModel(everythingWeKnewBefore, newInformation)
    

    随着新信息的到来,我们将其与之前发生的事情相结合,以产生新版本的“真相”。

    在 CQRS 世界中,这一切都发生在“写入模型”中 - 我们正在使用“真相”的权威表示,而不是过时的副本,并且我们会根据领域的要求对其进行修改。

    事件源部分实际上只是表示的不同:我们不是计算新状态,然后覆盖我们以前的副本,而是计算更改,并将这些更改附加到我们以前的(我们总是可以通过简单地枚举来重新计算状态)更改列表)。

    因此,我们的状态权威副本始终包含由领域模型按照写入顺序计算的事件。

    这里的主要模式是模型是系统中信息的权威,事件溯源只是存储该信息的另一种方式(一种支持时间查询的方式)。

    对于需要权威事件排序的解决方案部分,诀窍是您从事件存储中检索它们作为有序序列,不是通过一次读取它们并尝试重构序列。换句话说,您将使用拉模型,而不是推模型,将事件从一个系统传递到另一个系统。

    当您在基于推送模型的系统中工作时,事件可能会被错误排序,那么您需要将其构建到您的设计中。这往往以跟踪丢失哪些信息并等待它到达的形式发生。

    (您还必须更多地注意时间;消息到达时间是知道事情何时发生的相当有损的替代品。

    分布式系统是困难的,当一切都在本地时,我们学到的捷径不再适用。

    【讨论】:

      猜你喜欢
      • 2020-05-27
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多