为什么与eventSourcing

时间:2018-07-07 10:25:43

标签: architecture cqrs event-sourcing

我只是试图理解CQRS应用程序内部的数据流。 我了解很多机会,但有一点对我来说是一些问号。

场景:带有事件外包的CQRS。

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

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

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

所以它会按照流程查找我

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

当用户希望查看更新的聚合时,我的意见中包含以下数据流

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

现在,我的问题是:将事件再次应用于新构建的聚集体有什么好处?现在再次有验证。这一定是没用的工作。

谢谢大家!

2 个答案:

答案 0 :(得分:0)

  

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

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

请考虑以下顺序

  1. 我向您发送命令。
  2. 您向我发送了对该命令的确认。
  3. ???
  4. 我向您发送查询。
  5. 您向我发送了一个查询回复。

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

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

  

所以它会按照流程查找我

     
      
  1. 验证合计命令
  2.   

您实际上应该跟踪两种不同形式的验证。第一个问题是您的命令是否格式正确;消息中的所有字段是否具有正确的形状,是否存在所有必需的字段,依此类推。这些都是您可以不考虑聚合当前状态的检查。

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

  
      
  1. 从Aggreate / Commandhandler发送事件
  2.   

在模型外部可见事件之前,应将事件写入事件流(步骤6)。

  
      
  1. 再次销毁实例
  2.   

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

答案 1 :(得分:0)

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

这是您的意思吗?

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