CQRS - 如何处理新报告表(或:如何从事件存储中导入所有历史记录)

时间:2010-04-01 08:37:43

标签: domain-driven-design cqrs

我研究过一些CQRS样本实现(Java / .Net),它使用事件源作为事件存储,而简单(No)SQL存储作为“报告存储”。

看起来很不错,但我似乎在所有示例实现中都遗漏了一些东西。

如何在应用程序投入生产后处理新报表存储/屏幕的添加?以及如何将现有(最新)数据从事件存储导入新报表存储?

即:

想象一下基本的DDD / CQRS驱动的CRM应用程序。 每个屏幕(真的查看)都有自己的结构化报表存储(SQL表)。 使用侦听域事件(CustomerCreated / CustomerHasMoved等)的处理程序更新所有这些视图。

CRM的一个特点是它可以记录电话(PhoneCallLogged事件)。由于时间限制,我们只在CRM的V1中实现了电话记录的记录(查看和报告谁处理了哪个电话将在V2中实施)

在生产中运行一段时间后,我们希望为每位客户和销售代表实施已记录电话的“报告”。

因此,我们需要添加一些屏幕(视图)和支持报告表(在报告存储中),并用事件存储中已收集的数据填充...

这是我在看我研究的样品时卡住的地方。它们不处理将现有(历史)数据从事件存储导入(新)报表存储。

EventRepository(DomainRepository)的所有示例只有一个方法'GetById'和'Add',它们不支持一次性获取所有聚合根以填充新的报告表。

如果没有初始数据导入,新屏幕仅针对新发生的事件进行更新。不适用于已记录的电话(因为没有PhoneCallLogged事件的报告侦听器)

有任何建议和建议吗?

提前致谢,

REMCO

3 个答案:

答案 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'仅包含这些方法,因为您只需要在生产中使用它们。

为报告添加新的非规范化时,您可以将所有事件从开始发送给您处理程序。

您可以通过以下方式在开发网站上执行此操作:

  • 将您的事件日志加载到开发站点
  • 将所有事件发送到您的非规范化处理程序
  • 将新视图+处理程序移至生产网站
  • 运行发生在
  • 之间的事件
  • 现在你准备好了