为什么结合 eventSourcing 更新聚合实例很重要

Why is it important to update aggregate instance in combination with eventSourcing

我只是想了解 CQRS 应用程序中的数据流。 我了解很大一部分机会,但有一点对我来说是一些问号。

场景:CQRS 与 Eventsourcing。

在聚合中处理命令后,您将触发事件。

现在,我的问题是:为什么我必须在我的聚合中再次应用该事件。

public void Apply(TabOpened e)
{
    open = true;
}

所以它按照流程找我

  1. 发送命令
  2. 在聚合中验证命令
  3. 从 Aggreate/Commandhandler
  4. 发送事件
  5. 从 Eventstream 构建聚合实例
  6. 将事件应用于新更新的聚合
  7. 将新事件存储到 Eventstream
  8. 再次销毁实例

当用户想要查看更新后的聚合时,我认为有以下数据流

  1. 请求特定聚合
  2. 使用读取模型获取最新版本的聚合
  3. 观看汇总

现在我的问题是:将事件再次应用到新构建的聚合有什么好处。现在再次验证。这一定是无用的工作..

谢谢大家!

Now, my question is: Why i have to apply the Event again in my aggregate.

因为您希望聚合表示的本地副本与您写入持久存储的内容相匹配。

考虑以下序列

  1. 我给你发命令了
  2. 您向我发送了对该命令的确认。
  3. ???
  4. 我向您发送查询。
  5. 您向我发送查询-响应。

A 属性 我们希望您的服务具有:第 5 步中的查询-响应应该相同,无论第 3 步是 no-op 还是服务重启.

无论您是否使用“事件溯源”作为将状态从一个服务实例传递到下一个实例的持久机制,这 属性 都是可取的。

So it looks for me following process

  1. Validate Command in Aggregate

您应该跟踪两种不同形式的验证。首先是你的命令是否格式正确的问题;消息中的所有字段是否具有正确的形状,是否存在所有必填字段,等等。这些都是您可以 在不考虑 聚合当前状态的情况下进行的所有检查。

聚合处于当前状态时是否允许此命令是一个单独的想法。

  1. Send Event from Aggreate/Commandhandler

事件应该在模型外部可见之前写入事件流(您的第 6 步)。

  1. Destroy the instance again

你为什么要这么做?您当然可以从本地缓存中驱逐聚合实例;毕竟,您拥有在流中可用的恢复其状态所需的所有事件。但这不是必需的。

总结一下: 应用命令时,您通常会加载聚合。那么您想要更改聚合的状态,这意味着您添加了一个事件。我相信你的问题是:为什么你将事件应用到你的聚合而不只是将事件附加到事件存储,因为你无论如何都会在之后放弃聚合?

你是这个意思吗?

它基本上只是验证您将写入事件存储的内容可以并且将在您下次重新加载聚合时正确应用。此外,在处理正在更改聚合的命令时,可能需要执行多个步骤。第一步可能会改变状态并改变第二步的输出。