CQRS + EventSourcing.更改聚合根历史记录

Ale*_*nko 4 domain-driven-design cqrs event-sourcing

我有以下问题.给出.CQRS + EventSourcing应用程序.如何才能改变历史中聚合根的状态?

例如,会计应用程序,会计者想要应用转换但是过去的日期.将存储在Event Store中的事件将具有比最近事件更早的日期,但此事件的序列号将更大.

存储库将通过按序列号排序事件来恢复聚合根的状态.如果我们将拍摄过去日期的快照 - 我们将在没有此事件的情况下聚合根.

我们可以肯定地改变存储库的逻辑以按日期对事件进行排序,但是我们使用外部框架来进行CQRS,这是不可取的.

这种情况有一些优雅的解决方案吗?

CCo*_*ron 10

您正在寻找的是双时间实现.

例如,在12月3日,我们认为X == 12(as-at),但是在12月5日,我们纠正了错误,现在在12月3日知道X == 14(as-of)

有两种方法可以实现这一点

1)事件存储保存as-at数据,并且投影保存数据(可能的变化既是as-of,也是as-at投影)

2)聚合有一个重载方法,表示对事件存储的as-of和as-at值的期望.这很可能涉及使用自定义辅助快照流作为数据值.

您的解决方案很可能使用这两种实现,因为一个是以命令为中心而另一个是以查询为中心.

当收到纠正事件时,需要重建第二个选项中聚合根的as-of快照.

Martin Folwler在本文中谈到了这一点

注意:事件存储仍然仅附加.

  • 你应该把它标记为答案.谢谢, (2认同)

Den*_*aub 5

在会计中,如果你改变过去的预订,你可能会最终入狱.不要改变过去.改为使用补偿命令.

抱歉,您提出了会计示例,这可能是一个非常严格的关于摆弄过去的数据而不明确更改的域.

如果以上内容不适用于您的域,您可以轻松地在更改域名对象的状态(可能还有历史记录)的旧事件之上应用新事件.

例如,预订帐户.该事件可能在今天发生,但它可以将实际预订日期设置为过去的某个时间.


Hen*_*rik 2

您已声明您的业务逻辑允许您添加回溯交易;现在我不知道你为什么想要这样,但没有什么可以限制你的集体不接受它。当然,该事件将获得较晚的事件序列号/版本,但这是预期的。

您不需要摆弄基础设施、存储库或其他任何东西来执行此操作。