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