我想知道在使用某些事件采购解决方案重播事件时将事件应用到状态时应该包含哪些逻辑。
具体来说,我想知道验证,说我有实体可以处于以下状态之一:
并且进度需要记录 - >活动 - >关闭或记录 - >活动 - >取消,我们不能直接从记录跳转到关闭。例如。
现在,我理解,验证应该包含在命令中:UpdateState
将检查实体当前状态是否允许转换到所需的状态,并生成适当的事件StatusUpdated
,该事件将持久保存到事件商店。
问题是,重播时该怎么办?我应该只更新状态,还是应该执行相同的验证(如果状态转换要求发生变化,除非我们添加一些额外的逻辑,否则无法加载一些以前更新的实体),以确保我们不会最终那些不满足我们当前逻辑的实体?
PS。我认为我有把握它的问题,因为在我的理解中,事件本质上只是“宣布”已发生的事情(并且已经修改了发件人状态),以便有趣的各方可以做出相应的反应。如果事件加载/重放,你需要改变所述状态而不是实际“宣布”任何东西......
答案 0 :(得分:12)
重放事件流时无需执行任何验证。
命令模拟将来要完成的事情:你要求系统为你做些什么。由系统决定是否要这样做,例如,基于业务规则和验证。
事件对比已经发生的事情。就像在现实中一样,你无法改变过去。
因此,这意味着,当一个事件被持久化时,它是由于一个命令在处理它的时间点被视为有效的 。重播事件流只是意味着要查看过去发生的事情,而且您无法更改此事。
因此,您无需再次运行任何验证。
此外,这意味着如果有一天你的业务逻辑发生变化,过去发生的所有事情(商业事故!)仍然发生,所以他们不能改变。因此,您不能使用任何验证逻辑,因为它可能是今天的另一个验证逻辑,而不是存储事件时。
再次:你不能(也不应该)改变过去: - )
假设您有办法验证信用卡号码。客户来到您的商店,付款,根据您当前的规则,您认为他/她的卡是有效的,一切都很好。
然后,有一天,信用卡机构改变了信用卡号码的计算方式,因此您有另一种验证算法。
当您现在回放过去的事件时,付款已经发生,无论是否有新的验证规则 - 您都无法改变它已经发生的事实!如果您想要创建新的交易以将钱汇回给客户。同样,这将导致一个新事件,而不是过去发生过的事件。
因此,简而言之:不要针对任何事情验证事件。它们的定义是有效的,就像之前发生的那样。
答案 1 :(得分:2)
任何已写入事件存储的事件流都应该有效,无需在事件处理程序中引入任何逻辑即可进行回放。如果您需要更改过渡流程,则需要按照this example的行进行某种转换。
关于你的最后一点。事件采购是一种使用有序事件的历史记录来持久化和恢复实体状态的技术。只有这样,当您保存实体时,您还可以发布这些事件供任何感兴趣的人使用。