C# 域事件的并发性问题

C# 域事件的并发性问题,c#,.net,architecture,servicebus,C#,.net,Architecture,Servicebus,我有许多可以在我们的企业系统中调度的域事件。例如,如果有人创建或删除地址 我应该作为事件的一部分传递整个实体,还是只传递ID。消息通过服务总线发送并并行使用 如果我只是发送ID,那么如果同时发生删除,实体可能在消费者端不可用。我总是可以使用一个活动标志并将其设置为false,但是如果实体同时被更新,并且它更改了一些重要的内容呢 我该如何处理这些案件呢?我认为这是服务巴士上常见的难题,我相信没有一个完美的解决方案。我假设这里的范围只是重要域对象更改状态时引发的事件(即,不是事务命令,也不是读取/数

我有许多可以在我们的企业系统中调度的域事件。例如,如果有人创建或删除地址

我应该作为事件的一部分传递整个实体,还是只传递ID。消息通过服务总线发送并并行使用

如果我只是发送ID,那么如果同时发生删除,实体可能在消费者端不可用。我总是可以使用一个活动标志并将其设置为false,但是如果实体同时被更新,并且它更改了一些重要的内容呢


我该如何处理这些案件呢?

我认为这是服务巴士上常见的难题,我相信没有一个完美的解决方案。我假设这里的范围只是重要域对象更改状态时引发的事件(即,不是事务命令,也不是读取/数据服务)

决定只发送事件元数据,而不是发送完整的参考消息(例如,新的客户聚合根目录)可能比只发送与延迟相关的并发/版本控制问题有更广泛的影响,例如,这两种方法的一些优缺点:

最小
事件
元数据:

  • 具有更小的有效负载(如果您审核总线上的所有消息,则特别有用)
  • 可以很好地装入标准信封
  • 如果向未经授权的总线端点发送数据,则具有合理的安全性(系统只知道客户XYZ已更改,而不是实际的详细信息)
而完整的“聚合”根
消息
参考更新

  • 如果大多数订阅者对完整的有效负载不感兴趣,这可能会有点过头
  • 潜在的安全问题-并非总线上的所有订户都有权获得完整的有效负载
  • 但对于补充CQRS readstore缓存非常有用,因为一旦端点知道其数据已过时,就不需要返回真相来源获取数据—数据已经提供
因此,我想最终的决定将取决于您主要打算对EDA事件执行的操作(保持CQRS缓存更新、触发BPM工作流、监控CEP规则等)。您可能会决定采用混合方式,例如广泛广播事件数据,但随后只将完整消息路由到受信任的端点(事件元数据可能会从完整有效负载中投影,因此,在每次状态更改后,原始/真相来源系统仅能向总线发送一条消息有效负载)

要回答您的数据一致性问题,我相信您需要接受这样一个事实:数据最终是一致的,延迟将导致整个企业暂时的不一致。我认为这里最好的模式是向从原始真相来源获得的每条消息添加一个哈希或时间戳,这需要添加到任何使用此版本数据作为假设的命令中


然后,当命令处理系统处理该命令时,它可以根据当前的“真实”版本(基于实际的业务线系统数据库,而不是readstore缓存)检查该散列,如果哈希/时间戳不匹配(即乐观并发模式),则需要使命令失败。

是否使用eventstore?另外一点是,EDA事件是响应LOB系统上的命令而进行的。这些命令通常需要Ack/Nack样式的确认,尽管其目标是命令发起人(即不广播),因此此处也存在重叠。