architecture - 每个命令的事件溯源再水合?

标签 architecture domain-driven-design cqrs event-sourcing aggregateroot

我有一个以 CQRS 模式作为补充的事件源系统。 假设命令有效,向服务器发出的每个命令都会使用事件流将我的聚合(新初始化的聚合)重新水合到当前状态。

我的问题是 - 为什么我应该在每个命令中重新调整我的聚合状态?为什么我不能只为每个聚合 ID 保留一个聚合实例而不用担心重新保湿每个命令?在这种情况下,我只会在启动服务器时重新水化事件。

这样做有什么问题吗?它仍会保留状态历史,因为事件会继续保留。

谢谢!

编辑:我每隔 n 个事件就对我的聚合状态进行快照,因此我不必在每次重新水化时重新水化超过 n 个事件。此外,每次保存新快照以保存对状态的请求时,我都会缓存聚合状态。 我更想知道,如果我可以在内存中保留一个正在运行的聚合实例(每个 aggregateId),为什么还要重新水合

最佳答案

我同意@voiceofunreason 在几乎所有情况下(根据个人经验),存储\缓存“当前”聚合状态非常好。但是,您应该意识到这样做可能会遗漏一些东西:

  1. 您没有在运动中补充水分。这可能会隐藏版本控制问题足够长的时间,从而成为一个大问题。将此视为类似于对数据库进行备份,但从不测试恢复。
  2. 通过存储缓存,您将失去使用延迟事件的机会。例如,您可以有一个事件,如“新定价在 11 月之后适用”。一旦你拥有这个事件,你就会存储它,但它只会在特定日期之后影响状态(定价)。诚然,这是一种特定的(诚然不是特别常见的)情况,但这是您将要失去的东西。
  3. 您将无法进行(双)时态查询,例如“我当时对 X 聚合了解多少”。

第 1 点比其他点更重要,但有很多方法可以解决这个问题,而不是每次都实际补水。只是在很多情况下补液是一个不错的选择。

将快照与事件一起使用,并使用快照和更新的事件进行再水化解决了这些问题,因为:

  1. 重建直到你快照为止
  2. 当您遇到“延迟触发事件”时,由于快照与事件并排存储,因此很容易停止快照,直到延迟触发事件发生,之后您就可以拍摄快照了。<
  3. 您可以绕过临时查询的快照。

关于architecture - 每个命令的事件溯源再水合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51525140/

相关文章:

rest - CQRS、事件溯源和 Web 应用程序

c# - 如何使我的 appDomain 生命周期更长?

c# - 哪些体系结构可用于分解单一的 ASP.NET 网站?

ios - Swift/iOS - 在 View Controller 之间共享模型状态

web-services - 什么时候使用网络服务,什么时候不使用网络服务?

c# - DDD : Lazy loading in aggregates

domain-driven-design - DDD 中两个限界上下文之间的通信

domain-driven-design - Java 9 模块和 DDD 中的双重调度

c# - 在使用时对域对象进行更改

java - 命令消息-分类设计问题