如何在 CQRS 中处理基于集合的一致性验证?

发布于 2024-09-03 06:45:42 字数 586 浏览 9 评论 0原文

我有一个相当简单的域模型,涉及 Facility 聚合根列表。鉴于我使用 CQRS 和事件总线来处理从域引发的事件,您如何处理集合的验证?例如,假设我有以下要求:

  1. Facility 必须具有唯一的名称。

由于我在查询端使用最终一致的数据库,因此在事件处理器或处理事件时不能保证其中的数据是准确的。

例如,FacilityCreatedEvent 位于查询数据库事件处理队列中,等待处理并写入数据库。新的 CreateFacilityCommand 被发送到要处理的域。域服务查询读取数据库以查看是否有任何其他 Facility 已使用该名称注册,但返回 false,因为 CreateNewFacilityEvent 尚未处理和写入到商店。新的 CreateFacilityCommand 现在将成功并抛出另一个 FacilityCreatedEvent,当事件处理器尝试将其写入数据库并发现另一个 Facility 时,该事件将会爆炸。 code> 已以该名称存在。

I have a fairly simple domain model involving a list of Facility aggregate roots. Given that I'm using CQRS and an event-bus to handle events raised from the domain, how could you handle validation on sets? For example, say I have the following requirement:

  1. Facility's must have a unique name.

Since I'm using an eventually consistent database on the query side, the data in it is not guaranteed to be accurate at the time the event processesor processes the event.

For example, a FacilityCreatedEvent is in the query database event processing queue waiting to be processed and written into the database. A new CreateFacilityCommand is sent to the domain to be processed. The domain services query the read database to see if there are any other Facility's registered already with that name, but returns false because the CreateNewFacilityEvent has not yet been processed and written to the store. The new CreateFacilityCommand will now succeed and throw up another FacilityCreatedEvent which would blow up when the event processor tries to write it into the database and finds that another Facility already exists with that name.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

各自安好 2024-09-10 06:45:43

最终一致性和集验证:

  1. 如果问题很少见或不重要,请通过管理方式处理它,可能是通过向管理员发送通知。
  2. 调度 DuplicateFacilityNameDetected 事件,这可以启动自动解决过程。
  3. 维护一个了解所使用的设施名称的服务,可以通过侦听域事件并维护持久的名称列表来实现。在创建任何新设施之前,请先咨询此服务。

另请参阅此相关问题:使用 CQRS 和事件源时的唯一性验证

Three approaches are outlined in Eventual Consistency and Set Validation:

  1. If the problem is rare or not important, deal with it administratively, possibly by sending a notification to an admin.
  2. Dispatch a DuplicateFacilityNameDetected event, which could kick off an automated resolution process.
  3. Maintain a Service that knows about used Facility names, maybe by listening to domain events and maintaining a persistent list of names. Before creating any new Facility, check with this service first.

Also see this related question: Uniqueness validation when using CQRS and Event sourcing

夏雨凉 2024-09-10 06:45:43

在这种情况下,您可以实现一个简单的 CRUD 样式服务,该服务基本上在具有主键约束的 Sql 表中进行插入。

插入只会发生一次。当具有相同值且只应存在一次的重复命令命中聚合时,聚合调用服务,服务因违反主键约束而导致插入操作失败,抛出错误,整个过程失败且没有事件生成,在查询端没有报告,可能会在表中报告失败,以进行最终一致性检查,用户可以在其中查询以了解命令处理的状态。要检查这一点,只需使用命令 Guid 一次又一次查询命令状态视图模型即可。

显然,当该命令保存的值在进行主键检查的表中不存在时,操作成功。

主键约束表应该仅用作服务,但是,由于您实现了事件源,因此您可以重放事件以重建主键约束表。

In this case, you may implement a simple CRUD style service that basically does an insert in a Sql table with a primary key constraint.

The insert will only happen once. When duplicate commands with the same value that should only exist one time hits the aggregate, the aggregate calls the service, the service fails the Insert operation due to a violation of the Primary Key constraint, throws an error, the whole process fails and no events are generated, no reporting in the query side, maybe a reporting of the failure in a table for eventual consistency checking where the user can query to know the status of the command processing. To check that, just query again and again the Command Status View Model with the Command Guid.

Obviously, when the command holds a value that does not exists in the table for primary key checking, the operation is a success.

The table of the primary key constraint should be only be used as a service, but, because you implemented Event sourcing, you can replay the events to rebuild the table of primary key constraint.

夏至、离别 2024-09-10 06:45:43

由于唯一性检查会在数据写入之前完成,因此更好的方法是构建一个事件跟踪服务,该服务会在进程完成或终止时发送通知。

Because uniqueness check would be done before data writing, so the better method is to build a event-tracking service, which would send a notification when the process finished or terminated.

‖放下 2024-09-10 06:45:42

我采用的解决方案是添加一个System聚合根,它可以维护当前Facility名称的列表。创建新的Facility时,我使用System聚合(只有一个System作为全局对象/单例)作为它的工厂。如果给定的设施名称已经存在,则会抛出验证错误。

这将验证约束保留在域内,并且不依赖于最终一致的查询存储。

The solution I went with was to add a System aggregate root that could maintain a list of the current Facility names. When creating a new Facility, I use the System aggregate (only one System as a global object / singleton) as a factory for it. If the given facility name already exists, then it will throw a validation error.

This keeps the validation constraints within the domain and does not rely on the eventually consistent query store.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文