9

我被要求在事件源中进行一些探索。我的目标是创建一个满足所有传统CRUD操作的小API层。我现在正在使用一个名为'sourced'的包,并尝试使用它(使用Nodejs)。如何管理事件源应用程序中的读取请求

但是,当我单独使用时,我意识到事件源并不是很有用。通常,它与CQRS耦合。

我对CQRS的理解是,当UI向服务器发送写命令时。该应用程序对数据做了一些验证。并保存在事件存储(我用的MongoDB),例如:这里是我的事件存储应该是什么样子:

{method:"createAccount",name:"user1", account:1} 
{method:"deposit",name:"user1",account: 1 , amount:100} 
{method:"deposit",name:"user1",account: 1 , amount:100} 
{method:"deposit",name:"user1",account: 1 , amount:100} 
{method:"withdraw",name:"user1",account1,amount:250} 

它包含了所有审计信息,而不是最终的状态。然而,我很困惑我该如何处理读取操作。如果我想读取帐户的余额,该怎么办?究竟会发生什么? 这里是我的问题:

  1. 如果我们不能直接查询事件存储(数据库)用于读取操作,那么我们应该从哪里查询?它应该是内存中的缓存吗?
  2. 如果我们查询内存。是已经存在的最终状态,或者我必须执行重放(或左侧)操作来计算结果。例如,帐户1的余额为50.
  3. 我发现一些博客讨论了'订阅'或'广播'。他们是什么,并向谁播放?

如果我的理解错误,我会非常感谢您的任何建议,并请告诉我。

+0

对我来说,你不会在你的问题中表达意识的一个概念是事件通常在流中维护,这是按照DDD意义上的每个聚合分离的。在决策过程中考虑的事件序列仅限于您在写作时所处理的事件。在查询方面,您可以在某些低负载情况下通过阅读+折叠整个流来破解它。一般来说,正如答案所暗示的那样,预测是如何实现查询的等价物。 [GES介绍文档](http://docs.geteventstore.com/introduction/4.0.2/event-sourcing-basics/)是一个很好的阅读 –

+1

@RubenBartelink是的你是对的!我不知道如何使用事件流。我应该看看流维护的东西。感谢您的建议! – nick

回答

6

伟大的问题尼克。你错过的概念是'预测'。当事件持续时,您就可以播放该事件。您的投影代码侦听特定事件,然后执行更新等操作并创建“读取模型”。读取的模型是最终状态的一个版本(通常是持久的,但可以在内存中完成)。

好的是,你可以高度优化这些阅读模型的阅读。告别复杂和低效的联接等。

因为读取模型不是真相的来源,它是专门为阅读而设计的,因此可以在其中进行数据复制。只要确保您在收到适当的事件时进行管理。

欲了解更多信息请参阅以下文章:

希望你找到这些有用的。

**该图表示非正规化,它应该讨论预测。

+0

你的回答消除了我的困惑!非常感谢!我现在正在实施一个小型银行存款/提款申请。事件发生后。我广播了这个事件(例如“存款”),并且正在聆听“存款”的相应部分将处理此存款事件以更新余额。它是否正确? – nick

+0

顺便说一下,我们假设我在数据库中有数百万条记录。这是否意味着如果我重新启动服务器。可能需要一段时间才能初始化要更新的ReadModel? – nick

+0

几乎在您的第一条评论。改变命名和事件的名称。命令是必要的,事件总是过去式。关于重新初始化。重新启动应用程序不应该比其他应用程序更长。你应该坚持阅读模型。希望这是有道理的。 – Codescribler

3

您可以查询事件存储。实际的查询方法特定于每个实现,但通常情况下,您可以轮询事件或订阅,并在新事件持续时通知。

事件存储区只是写入端的持久性,保证了写入操作的强大一致性以及读取操作的最终一致性。为了从事件中“理解”某些东西,需要将这些事件投影到读取模型中,然后查询读取模型。例如,您可以将读取模型作为MongoDB集合包含每个帐户的当前余额。

+1

谢谢!你的回答帮助我理解它!我现在正在向听众实施广播,然后听众可以处理相应的方法(例如,'撤销') – nick

+0

@不用欢迎您! –

相关问题