2017-09-13 42 views
0

我们正在使用使用的NodeJS微服务,CQRS,事件存储CQRS域,一切就像一个魅力和典型的流程是这样:CQRS +微服务处理事件的回滚

  1. REST-> 2。服务 - > 3。命令验证 - > 4。命令 - > 5。聚集物> 6。事件 - > 7。事件库(事务数据) - > 8。返回聚合ID-> 9.存储在微服务本地数据库(本质上是读数据库) - > 10.发布事件到队列

上面的流程的问题是,由于事务数据保存,即持久性到事件存储和存储到微服务的读取数据发生在不同的事务上下文中,如果在步骤9有任何失败,我应该如何处理已经传播到事件存储的事件和已经更新的聚合?

任何建议将不胜感激。

+0

究竟是什么“9.存储在微服务本地数据库(本质上是读数据库)”? –

+0

它是读取数据库的读取数据库,像GET,GETALL等发生的那样。 – vaibhav

+0

它看起来像是将数据库中的聚合状态保存在数据库中?什么是第8步? –

回答

0

内您的活动的商店,你可以跟踪是否读端复制成功。 只要步骤9结束,您可以将事件标记为“已复制”。

这样的话,你可能会引入留意无重复事件,并触发第9步您也可以跟踪复制是否失败多次的组件。

更新读出侧(步骤9),并作为复制应该一致地发生flagigng的事件。你可以在这里使用传奇模式。

+2

事件存储是仅附加的,并且事件不应该知道它们的使用位置。我会说它是readmodel应该知道有多少事件已经应用到它,并且事件库应该能够分辨出流中的任何特定事件具有哪个“序列号”。因此,如果您的readmodel应用了120个事件并接收到事件#122,它应该向事件库 –

+0

请求丢失事件。谢谢,这确实是更清晰的方法。 – mbnx

+0

我正在使用的活动商店对已发送和未发放的活动进行了明确区分,这些活动完全遗漏了,我相信这就是问题的答案所在。我信任的佐贺模式更多的是关于不同集合的服务如何处理它们之间的业务依赖关系,而不是我信任的东西是在这种情况下使用的模式。 。 – vaibhav

3

上述流程的问题是,由于事务数据保存即事件存储和存储到微服务的读数据的持久性发生在不同的事务上下文中,如果在步骤9有任何失败,应该如何处理已经传播到事件存储的事件和已更新的聚合?

您稍后重试。

的“记录书”是事件商店。下游视图(“发布的事件”,阅读模型)来自记录簿。它们通常落后于时间记录簿(eventual consistency),并且通常不会彼此同步。

所以,你可能有,在某个时间点,105个事件上写本书的记录,但只有100发布到队列,并在服务数据库中表示只从98

更新一个构建视图通常以两种方式之一完成。当然,您可以从全新的表现开始,并在每次更新中重播所有事件。或者,您可以追踪视图的元数据中的事件历史记录,并使用该信息确定事件历史记录的下一次读取开始的位置。

+0

这几乎可以回答它,实际上我缺少的是派遣和未分派的事件。在这种情况下,无论它在读取的数据块上写什么,这里的事件都会生成,但它们的区别在于它会在未发送的事件表中出现。 – vaibhav

0

我想我现在已经更好地理解它了。 Aggregate仍然会被创建,答案是任何类型的一致性的所有验证都应该在我的聚合被构造之前发生,这是在代码的权限范围内发生故障的情况下,在更新读取侧数据库时存在故障需要处理的微服务。 因此,在理想情况下会创建聚合,但是相关的事件将保持未分配状态,除非更新所有读取依赖关系,否则将保持未分配状态并且可以单独处理。 活动商店仍将保留所有活动,并保持最终一致性。

+0

当您有多个读取边时,您如何处理这些(未分派的)事件? (具有自动故障转移和负载平衡,基于服务器负载启动和停止实例)。活动商店如何确定有多少活动消费者必须说“是”? –