CQRS-基于来自多个投影的决策应用命令

问题描述 投票:0回答:1

问题与CQRS有关-我有一个用户想从Web上订购商品,并向其显示GUI,显示其余额= 100 $,库存= 1。假设我们在AccountServiceStockService中有2个服务,它们有各自的关注点。为了为客户端第三项服务生成GUI,AggregatorService侦听来自AccountServiceStockService的域事件,设计视图并为客户端创建GUI。

当用户决定订购该项目时,他单击按钮,并将订购命令发送到AccountService。在这里,我们加载AccountAggregate,以减少需要订购的商品价格的余额。但是在执行此操作之前,我必须检查该物品是否仍然可用(或以某种方式保留它)。我唯一想到的是:

  • [从StockService的读取模型中读取项目的当前库存,但是可能发生的是,其他服务读取模型在我读取它后仅一秒钟就更新了(例如,有人购买了该项目,因此实际库存为= 0。但是,读取的模型仍为= 1)。
  • [减少余额前,请在StockService上调用某些方法以保留该项目一段时间。如果订购不成功(例如,余额不足,我将不得不以某种方式取消预订)。这需要进行一些sync-REST调用,并且可能比某些异步解决方案(如果有)要慢。

这种用例是否有最佳实践?

domain-driven-design cqrs event-sourcing
1个回答
0
投票

您有2个选择,具体取决于您是否接受最终的一致性。对于您已命名的所有服务,我假设您都不是DDD,所以我会坚持以服务为导向。

使用立即一致性,我将拥有一个OrderService来接收订单请求,并且它将对AccountService.ReservePayment()和StockService.ReserveStock()进行异步调用。如果任何一个失败,则调用AccountService.UndoReservePayment()和StockService.UndoReserveStock()。如果两者均成功,则调用AccountService.CompleteReservePayment()和StockService.CompleteReserveStock()。确保每个保留都应带有时间戳,以便守护程序进程可以偶尔运行,并撤消所有早于一个小时左右的保留。

此方法使用户等待,直到这两个服务都完成。如果StockService或AccountService都很慢,则用户体验很慢。我建议一个更好的方法是最终的一致性方法,该方法可以为用户提供非常快的体验,但会在事发后接收失败消息。

最终,您会假设他们有足够的信誉并且您有足够的库存,并且根据他们的订单要求,您会立即发送回成功消息。用户很高兴,他们继续购买更多东西。

然后,如上所述对OrderCreated事件进行异步处理以保留库存和贷方。但是,由于没有时间上的压力来回复等待的用户,因此您不必扩大规模即可处理如此高的吞吐量。如果信用检查和存货检查需要一两分钟,那么用户将不在乎,因为他没有做其他事情。

您在这里支付的价格是,用户在提交订单时可能会收到一条成功消息,然后在几分钟后收到一封电子邮件,说明销售毕竟没有进行,因为没有库存。这是许多大型零售商(包括Amazon,Target,Walmart等)所做的事情。最终的一致性可以大大减轻后端的负载和成本。

© www.soinside.com 2019 - 2024. All rights reserved.