events - CQRS/ES 架构上的补偿事件

标签 events cqrs event-sourcing eventstoredb

所以,我正在做一个 CQRS/ES 项目,在这个项目中,我们对如何处理在其他架构中很容易处理的琐碎问题有一些疑问

我的情况如下:

我有一个客户 CRUD REST API,每个客户都有唯一的文档(编号),所以当我注册一个新客户时,我必须验证是否有另一个客户使用该文档以避免重复,但是当涉及到 CQRS/ES 架构最终实现了一致性,我发现这种验证很难解决。

需要注意的是,我的问题不是跨微服务,而是在同一个微服务的命令应用和查询应用之间。

我们也在使用 eventstore .

我目前的解决方案:

所以我今天要做的是,在我的命令应用程序中,在保存 CustomerCreated 事件之前,我询问查询应用程序(使用 PostgreSQL)是否有该文档的客户,如果没有,我允许该事件继续进行。但这并不能保证 100%,对吧?因为我的查询可以去同步,所以我不能 100% 信任它。那是我的第二次验证开始的时候,当我的查询应用程序正在处理事件并将它们保存到我的 PostgreSQL 时,我再次检查该文档是否有客户,如果有,我拒绝该事件并发出一个补偿事件以撤消/cancel/inactivate 使用重复文档的客户,从而在 eventstore 上完成该客户流。

尽管这可行,但这里有两件事困扰着我,第一件事是我的命令应用程序依赖于查询应用程序,所以如果我的查询应用程序关闭,我的命令就会受到影响(今天,如果查询是,我只是在验证时返回 false下降但仍然......)第二件事是,查询/读取模型真的应该能够发出事件吗?如果是这样,正确的做法是什么?该命令是否应该为此提供某种 API?或者查询是否应该使用一些公共(public)共享库将事件直接发送到事件存储?如果我有多个 View /阅读?我应该选择哪一个来处理这个?

真的希望有人能阐明这些问题并帮助我解决这些问题。

最佳答案

作为引用,您可能需要查看 Greg Young 所写的关于 Set Validation 的内容。 .

I ask the query application (using PostgreSQL) if there is a customer with that document, and if not, I allow the event to go on. But that doesn't guarantee 100%, right?


完全正确 - 您的读取模型是陈旧的副本,并且可能没有写入模型收集的所有信息。

That's when my second validation kicks in, when my query application is processing the events and saving them to my PostgreSQL, I check again if there is a customer with that document and if there is, I reject that event and emit a compensating event to undo/cancel/inactivate the customer with the duplicated document, therefore finishing that customer stream on eventstore.


这种拼写与通常的设计不太匹配。更常见的实现是,如果我们在读取数据时检测到问题,我们会向写入模型发送一条命令消息,告诉它理顺事情。
这通常被称为流程管理器,但您可以将其视为 human supervisor of the system 的自动化。 .从概念上讲,流程管理器是要发送到命令模型的消息的事件源集合。
您可能还需要考虑是否正确地对域进行建模。如果文档应该是唯一的,那么命令模型可能应该使用文档编号作为记录簿中的键,而不是使用客户。或者文档 ID 应该是客户数据的函数,而不是任意输入。

as far as I know, eventstore doesn't have transactions across different streams


对 - 一般来说,您真正需要考虑的一件事是您的流边界在哪里。如果集合验证具有重要的商业值(value),那么您确实需要考虑将整个集合放入单个流中(或者通过找到一种方法来限制唯一性而不使用集合)。

How should I send a command message to the write model? via API? via a message broker like Kafka?


那是管道;只要您确定该命令在其自己的事务/工作单元中运行,您如何执行它并不重要。

关于events - CQRS/ES 架构上的补偿事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49451237/

相关文章:

javascript - 页面重新加载后,this.id 在 onchange 事件中未定义

c# - 为什么 GetByID 是命令而不是查询?

java - Axon从2.4.3版本迁移到3.1.1有什么具体方法

c# - CQRS NServiceBus UI 反馈

java - CQRS 如何避免命令和事件之间的重复字段?

C# Web 浏览器控件阻止父级的加载事件

javascript - 如果鼠标离开父元素则隐藏元素

javascript - 将其传递到 map 上的点击处理程序中

events - 事件源: where to put business logic

domain-driven-design - 如何设计从面向CRUD的旧版应用程序到CQRS和事件源系统的桥梁?