3

我想知道在使用某些事件源解决方案重播事件时将事件应用于状态时应该包含哪些逻辑。

具体来说,我想知道验证,比如说我有一个可以处于以下状态之一的实体:

  • 已记录
  • 积极的
  • 关闭
  • 取消

而进度需要Logged->Active->Close或者Logged->Active->Cancelled,比如不能直接从Logged跳转到Close。

现在,我理解,验证应该包含在命令中:UpdateState将检查实体当前状态是否允许转换到所需的状态,并产生适当的事件StatusUpdated,该事件将持久保存到事件存储中。

问题是,回放时我应该怎么做?我应该只更新状态,还是应该执行相同的验证(这样如果状态转换要求发生变化,除非我们添加一些额外的逻辑,否则无法加载一些以前更新的实体),以确保我们不会最终得到不满足我们当前逻辑的实体?

PS。我认为我在理解它时遇到了问题,因为在我的理解中,事件本质上只是“宣布”已经发生的事情(并且发送者状态已经被修改),以便有趣的各方可以做出相应的反应。并且在事件加载/重播的情况下,您需要更改所述状态而不是实际“宣布”任何事情......

4

2 回答 2

11

重放事件流时不需要执行任何验证。

命令为将来要做的事情建模:您要求系统为您做某事。由系统决定是否执行,例如基于业务规则和验证。

相比之下,事件模拟了已经发生的事情。正如在现实中,你无法改变过去。

因此,这意味着,当一个事件被持久化时,它是一个在处理它的时间点被视为有效的命令的结果。重放事件流只是意味着查看过去发生的事情,您无法更改这一点。

因此,您无需再次运行任何验证。

而且,这意味着如果有一天你的业务逻辑发生变化,过去发生的所有事情(业务事故!)仍然发生,所以它们一定不能改变。因此,您不允许使用任何验证逻辑,因为今天可能是另一个验证逻辑,而不是您存储事件时的验证逻辑。

再说一遍:你不能(也不应该)改变过去:-)

例子

假设您有一种验证信用卡号码的方法。客户来到您的商店,付款,根据您当前的规则,您认为他/她的卡是有效的,一切都很好。

然后,有一天信用卡机构改变了信用卡号码的计算方式,因此你有了另一种验证算法。

当您现在回放您过去的事件时,无论是否有新的验证规则,付款已经发生——您无法改变它已经发生的事实!如果你愿意,你必须创建一个新的交易来将钱寄回给客户。同样,这将导致一个新的事件,而不是一个从过去改变的事件。

所以,长话短说:不要针对任何事情验证事件。根据定义,它们是有效的,就像它们之前发生的那样

于 2013-05-03T11:37:51.257 回答
2

任何写入事件存储的事件流都应该是有效的,可以在没有在事件处理程序中引入任何逻辑的情况下进行回放。如果您需要更改过渡过程,则需要按照本示例的思路进行某种转换。

关于你的最后一点。事件溯源是一种使用有序事件的历史记录来持久化和恢复实体状态的技术。碰巧的是,当您保存实体时,您还可以发布这些事件以供任何相关方使用。

于 2013-05-03T11:31:26.143 回答