在 CQRS 模式 + 事件溯源中读取"latest data"的使用模式



我正在用CQRS(命令查询责任分离)模式实现一个测试项目。

我有几个问题。

  1. 我想在购买前查看用户购物车上商品的数据存储的最新价格。因此,real_model(通过物化视图)价格将根据数据存储(产品表)上的最新价格进行检查。如果价格之间存在差异,我想向用户显示警报。实现这一目标的最佳方式是什么?

  2. 当用户更新他们的电子邮件和密码时,它应该仍然依靠创建事件来更新数据存储(事件->事件存储->服务总线->数据存储)还是直接更新数据存储?我不希望触发read_model_update的事件延迟,因为用户必须立即登录。

我想在购买之前在数据存储中查看用户购物车上商品的最新价格。。。实现这一目标的最佳方式是什么?

我的怀疑是,"实现这一目标的最佳方式"在很大程度上取决于利益相关者想要为客户提供的购物体验。IE-价格应该在什么时候锁定?例如,购物车上显示的价格可能是有时间限制的实盘。

但为这些细节开脱。。。

一种方法是在调度命令之前对读取模型运行健全性检查。有一种常见的模式,即(有效地)检查在读取模型的状态下命令是否有效,然后调度临时验证的命令来更新记录簿。您可以用一些延迟来换取降低的故障率。

另一种可能性是使用流程管理器;其思想是"placeOrder"不是对模型的简单写入,而是生命周期的开始。因此,例如,假设报价是模型中的一个东西——当一个项目被放在购物车中时,就会生成一个报价(可能有一些过期值)。当价格发生变化时,所有不同的报价都会更新。下订单时,处理程序会看到placedOrder事件,并尝试在报价上调用acceptQuote方法;如果报价仍然有效,则生成的事件会将订单过程推进到下一个状态。如果报价不再有效,则会生成不同的事件,或者命令被拒绝,最终超时显示可能存在问题。。。。

(您可以尝试对产品本身进行类似的操作,但由于争用问题,操作不太好;要知道您正在使用对象的最新状态,唯一的方法就是让记录簿接受对它的写入。)

这可能是有用的审查种族条件不存在由乌迪·达汉。

当用户更新他们的电子邮件和密码时,它应该仍然依靠创建事件来更新数据存储(事件->事件存储->服务总线->数据存储)还是直接更新数据存储?

没有直接更新——读取模型的所有更新都应该在记录簿更新之后进行。

我不希望触发read_model_update的事件延迟,因为用户必须立即登录。

用户可以立即重新登录,但这并不意味着你需要立即确认登录。

例如;通过write模型,您刚刚发布了一系列新的事件。获取已发布的最高事件的序列号,并将查询的这一部分发送到读取模型;登录处理程序将该序列号与读取模型中可用的序列号进行比较,如果模型需要另一个心跳来跟上,则会暂停。

(更有可能的是:在这种用例中,在事件发布系统和客户端的后续请求之间存在竞争,您会安排一个读取模型,根据需要查询事件存储。因此,您的延迟基本上是读取模型和记录系统之间的网络距离,加上应用新事件所需的时间的函数effect,来自客户端的请求充当指示高水位线已经增加的事件消息,然后模型调度查询以获取丢失的历史)。

还要注意其推论——读取模型的不同部分有不同的延迟要求。

CQRS是一种空壳游戏。仍然只有一个记录系统,即接受模型写入的持久性存储。该存储已针对写入进行了优化。读取模型可以附加到该存储(获取最新的可用数据,但由于数据处于"写优化"形式,因此具有额外的处理延迟),也可以附加到存储的投影(其中数据较旧,但已针对特定读取进行了优化)。

最新更新