在事件来源中如何处理一致性违规? [英] How are consistency violations handled in event sourcing?

查看:185
本文介绍了在事件来源中如何处理一致性违规?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,让我说一下我对命令查询职责隔离和事件源(消息驱动器体系结构)还是陌生的,但是我已经看到了一些重大的设计优势。但是,还有一些我不清楚的问题。



说我有一个 Customer 类(包含一个名为 postalAddress 的属性( Address 类的实例,它是一个值对象)的聚合根) 。我也有一个 Order 类(另一个聚合根),该类包含(在 OrderItem 对象和其他东西中) deliveryAddress (也是 Address 类的实例)和名为 status的字符串属性



客户通过发出 PlaceOrder 命令下订单,该命令触发 OrderReceived 事件。此时,订单状态为已接收 。订单发货后,仓库中的某人会发出 ShipOrder 命令,该命令会触发 OrderShipped 事件。此时,订单状态为已发货



其中一项业务规则是如果 Customer 在发货之前更新了他们的 postalAddress (即状态仍为已接收 ),还应更新 Order 对象的 deliveryAddress 。如果订单的状态已经是已发货 ,则 deliveryAddress 不会被更新。



问题1.是将这种有条件级联的地址更新放入Saga(即流程管理器)的最佳位置)?我假设是这样,因为它将事件(客户刚刚更新了他们的邮寄地址...)转换为命令( ...因此更新了订单123的送达地址)。



问题2。如果Saga是工作的正确工具,那么鉴于汇总只能



继续,假设每个集合代表一个事务边界,如果系统要客户的 postalAddress 的更新后<崩溃>( CustomerAddressUpdated 事件被保留到事件存储中),但 bef矿石 OrderDeliveryAddressUpdated 可以被更新(即在两次交易之间),然后系统处于不一致状态。



问题3.如何发现和纠正这种一致性规则的违反行为?

解决方案

在大多数情况下,订单的交付地址应独立于其他任何数据更改,因为客户可能希望将订单发送到任意地址。话虽如此,我将在方法上给我2c评分:


是在流程管理器中处理此问题的最佳位置?


是。您应该有一个 OrderProcess


一个人如何掌握正确的 OrderProcess 实例是否只能通过聚合ID检索?


有没有什么可以阻止人们添加任何其他将数据与聚合ID相关联的查找机制的。在我的实验性,即将上线的机制中,称为 shuttle-recall 的我有一个 IKeyStore 机制,将任意密钥与AR ID关联。这样,您就可以将诸如 [order-process]:customerId = CID-123; 之类的内容关联为某个聚合的键。


如何检查和纠正这种一致性规则的违反?


在如果可能,大多数情况下可以带外处理。我是否应该从亚马逊订购商品,并在订单发货后尝试更改地址,所以订单仍将返回原始地址。如果您将客户的邮政地址链接到有效的订单地址,则可以通知客户 n 个订单的地址已更新,但最近的订单(在一定容忍度内)没有更新。 / p>

至于系统在处理之前发生故障,您应该具有一定的保证交付机制来处理此问题。我对这些域事件的看法与对诸如服务总线之类的消息传递基础结构中的系统事件的看法不同。



只是有些想法:)


First of all, let me state that I am new to Command Query Responsibility Segregation and Event Sourcing (Message-Drive Architecture), but I'm already seeing some significant design benefits. However, there are still a few issues on which I'm unclear.

Say I have a Customer class (an aggregate root) that contains a property called postalAddress (an instance of the Address class, which is a value object). I also have an Order class (another aggregate root) that contains (among OrderItem objects and other things) a property called deliveryAddress (also an instance of the Address class) and a string property called status.

The customer places an order by issueing a PlaceOrder command, which triggers the OrderReceived event. At this point in time, the status of the order is "RECEIVED". When the order is shipped, someone in the warehouse issues an ShipOrder command, which triggers the OrderShipped event. At this point in time, the status of the order is "SHIPPED".

One of the business rules is that if a Customer updates their postalAddress before an order is shipped (i.e., while the status is still "RECEIVED"), the deliveryAddress of the Order object should also be updated. If the status of the Order were already "SHIPPED", the deliveryAddress would not be updated.

Question 1. Is the best place to put this "conditionally cascading address update" in a Saga (a.k.a., Process Manager)? I assume so, given that it is translating an event ("The customer just updated their postal address...") to a command ("... so update the delivery address of order 123").

Question 2. If a Saga is the right tool for the job, how does it identify the orders that belong to the user, given that an aggregate can only be retrieved by it's unique ID (in my case a UUID)?

Continuing on, given that each aggregate represents a transactional boundary, if the system were to crash after the Customer's postalAddress was updated (the CustomerAddressUpdated event being persisted to the event store) but before the OrderDeliveryAddressUpdated could be updated (i.e., between the two transactions), then the system is left in an inconsistent state.

Question 3. How are such "violations" of consistency rules detected and rectified?

解决方案

In most instances the delivery address of an order should be independent of any other data change as a customer may want he order sent to an arbitrary address. That being said, I'll give my 2c on how you could approach this:

Is the best place to handle this in a process manager?

Yes. You should have an OrderProcess.

How would one get hold of the correct OrderProcess instance given that it can only be retrieve by aggregate id?

There is nothing preventing one from adding any additional lookup mechanism that associates data to an aggregate id. In my experimental, going-live-soon, mechanism called shuttle-recall I have a IKeyStore mechanism that associates any arbitrary key to an AR Id. So you would be able to associate something like [order-process]:customerId=CID-123; as a key to some aggregate.

How are such "violations" of consistency rules detected and rectified?

In most cases they could be handled out-of-band, if possible. Should I order something from Amazon and I attempt to change my address after the order has shipped the order is still going to the original address. If your case of linking the customer postal address to the active order address you could notify the customer that n number of orders have had their addresses updated but that a recent order (within some tolerance) has not.

As for the system going down before processing you should have some guaranteed delivery mechanism to handle this. I do not regard these domain event in the same way I regard system events in a messaging infrastructure such as a service bus.

Just some thoughts :)

这篇关于在事件来源中如何处理一致性违规?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆