我有一个以 CQRS 模式作为补充的事件源系统。 假设命令有效,向服务器发出的每个命令都会使用事件流将我的聚合(新初始化的聚合)重新水合到当前状态。
我的问题是 - 为什么我应该在每个命令中重新调整我的聚合状态?为什么我不能只为每个聚合 ID 保留一个聚合实例而不用担心重新保湿每个命令?在这种情况下,我只会在启动服务器时重新水化事件。
这样做有什么问题吗?它仍会保留状态历史,因为事件会继续保留。
谢谢!
编辑:我每隔 n 个事件就对我的聚合状态进行快照,因此我不必在每次重新水化时重新水化超过 n 个事件。此外,每次保存新快照以保存对状态的请求时,我都会缓存聚合状态。 我更想知道,如果我可以在内存中保留一个正在运行的聚合实例(每个 aggregateId),为什么还要重新水合。
最佳答案
我同意@voiceofunreason 在几乎所有情况下(根据个人经验),存储\缓存“当前”聚合状态非常好。但是,您应该意识到这样做可能会遗漏一些东西:
- 您没有在运动中补充水分。这可能会隐藏版本控制问题足够长的时间,从而成为一个大问题。将此视为类似于对数据库进行备份,但从不测试恢复。
- 通过存储缓存,您将失去使用延迟事件的机会。例如,您可以有一个事件,如“新定价在 11 月之后适用”。一旦你拥有这个事件,你就会存储它,但它只会在特定日期之后影响状态(定价)。诚然,这是一种特定的(诚然不是特别常见的)情况,但这是您将要失去的东西。
- 您将无法进行(双)时态查询,例如“我当时对 X 聚合了解多少”。
第 1 点比其他点更重要,但有很多方法可以解决这个问题,而不是每次都实际补水。只是在很多情况下补液是一个不错的选择。
将快照与事件一起使用,并使用快照和更新的事件进行再水化解决了这些问题,因为:
- 重建是直到你快照为止
- 当您遇到“延迟触发事件”时,由于快照与事件并排存储,因此很容易停止快照,直到延迟触发事件发生,之后您就可以拍摄快照了。<
- 您可以绕过临时查询的快照。
关于architecture - 每个命令的事件溯源再水合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51525140/