我研究了一些使用事件源作为事件存储的CQRS样本实现(Java / .Net)和一个简单的(No)SQL存储作为“报告存储”。
看起来很好,但我似乎在所有示例实现中都缺少某些东西。
在应用程序投入生产后,如何处理新报表存储/屏幕的添加?以及如何将现有(最新)数据从事件存储导入新报表存储?
即:
想象一下基本的DDD / CQRS驱动的CRM应用程序。
每个屏幕(真的查看)都有自己的结构化报表存储(SQL表)。
所有这些视图都使用侦听域事件(CustomerCreated / CustomerHasMoved等)的处理程序进行更新。
CRM的一个特点是它可以记录电话呼叫(PhoneCallLogged事件)。由于时间限制,我们只在CRM的V1中实现了电话记录的记录(查看和报告谁处理了哪个电话将在V2中实施)
在生产运行一段时间后,我们希望实现每个客户和销售代表记录的电话呼叫的“报告”。
因此,我们需要添加一些屏幕(视图)和支持报告表(在报告存储中),并用事件存储中已收集的数据填充它...
这是我在看我研究的样品时卡住的地方。它们不处理将现有(历史)数据从事件存储导入(新)报表存储。
EventRepository(DomainRepository)的所有示例只有一个方法'GetById'和'Add',它们不支持一次性获取所有聚合根以填充新的报告表。
如果没有初始数据导入,新屏幕仅针对新发生的事件进行更新。不适用于已记录的电话(因为没有PhoneCallLogged事件的报告侦听器)
有什么建议,建议吗?
提前致谢,
REMCO
您在现有事件日志上重新运行处理程序(例如,您通过新事件处理程序播放旧事件)
以您为例...您的事件日志中有大量的PhoneCallLoggedEvents。带上你的新手柄并通过它播放所有旧事件。它就像它一直在运行,并将继续处理任何到达的新事件。
干杯,
格雷格
您在现有事件日志上重新运行处理程序(例如,您通过新事件处理程序播放旧事件)
以您为例...您的事件日志中有大量的PhoneCallLoggedEvents。带上你的新手柄并通过它播放所有旧事件。它就像它一直在运行,并将继续处理任何到达的新事件。
干杯,
格雷格
例如,在Axon Framework中,可以通过以下方式完成:
JdbcEventStore eventStore = ...;
ReplayingCluster replayingCluster = new ReplayingCluster(
new SimpleCluster("replaying"),
eventStore,
new NoTransactionManager(),
0,
new BackloggingIncomingMessageHandler());
replayingCluster.startReplay();
事件重放是一个尚未完全记录并且缺乏成熟工具的领域,但这里有一些起点:
'EventRepository'只包含这些方法,因为您只需要在生产中使用它们。
为报告添加新的非规范化时,您可以将所有事件从开始发送到您的处理程序。
您可以通过以下方式在开发站点上执行此操作:
- 将事件日志加载到开发站点
- 将所有事件发送到您的非规范化处理程序
- 将新视图+处理程序移动到生产站点
- 运行中间发生的事件
- 现在你准备好了