如何存储Sagas的数据?

时间:2018-11-06 14:39:09

标签: cqrs event-sourcing aggregateroot saga

据我所知,聚合必须仅包含用于保护其不变性的属性。

我还读到sagas可以是聚合体,这对我来说很有意义。

现在,我使用一个传奇来对注册过程进行建模:在RegistrationStarted事件上,它会发送一个ReserveEmail命令,如果电子邮件免费,它将触发一个EmailReservedEmailReservationFailed或不。然后,侦听器将发送验证链接或一条消息,告知帐户已经存在。

我想在此侦听器中使用来自RegistrationStarted事件的数据(例如IP和用户代理)。我该怎么办?

  • 将这些数据存储在传奇中?但是它们并不用于保护不变式。
  • 通过ReserveEmail命令和结果事件推动它们?听起来很乏味。
  • 将传奇故事投射到读取模型上?最终的一致性如何?
  • 另一种方式?

1 个答案:

答案 0 :(得分:2)

Rinat Abdullin wrote a good overview of sagas / process managers

通常的答案是,传奇具有它关心的事件的副本,并使用这些事件中的信息来计算要发送的命令消息。

List[Command] processManager(List[Event] events)
  

通过ReserveEmail命令和结果事件将其推送?

是的,这是通常的方法;我们得到一个列表[RegistrationStarted],然后使用它来计算结果[ReserveEmail]。稍后,我们将获得[RegistrationStarted, EmailReserved],我们可以使用它来计算下一组命令(如果有)。

  

听起来很乏味。

数据必须以某种方式在两种功能之间传递。因此,您要么将数据从一条消息复制到另一条消息,要么将correlation identifier从一条消息复制到另一条消息,然后让使用者决定如何使用相关标识符来获取数据的副本。 / p>

  

将这些数据存储在传奇中?但是它们并不用于保护不变式。

您通常将事件存储在sagas中(以跟踪发生的情况)。这样可以为您提供事件中提供的数据的副本。您没有要保护的不变式,因为您只是在缓存其他地方所作的决策的副本。通常,您不会让流程管理器运行查询来收集其他数据。

  

最终一致性如何?

从本质上讲,萨加斯始终会“最终保持一致”;传奇实例的“状态”只是在其他位置控制的数据的缓存副本。到传奇故事出现时,数据可能已经过了十亿分之一秒的时间,因此没有必要假装数据是“现在”。

  

如果我理解正确,我可以将我的传奇建模为一个注册聚合,以存储所有相关标识符为其自身标识符的事件?

Udi Dahan,writing about CQRS

  

这是最有力的暗示,我可以告诉您您在正确地执行CQRS:您的总根是无花果。