问题标签 [event-sourcing]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
5047 浏览

design-patterns - 对对象进行版本控制有哪些设计模式?

有哪些设计模式可以在对象更改时保留其历史记录。我不需要像事件溯源那样繁重的任务,只需要在特定事件发生时保存过去版本的能力(在这种情况下,当按下打印表单按钮时)。

0 投票
2 回答
8242 浏览

domain-driven-design - CQRS + DDD + 事件溯源中的聚合间通信

在基于 DDD 原则构建的环境中,使用事件源聚合后端,单独的聚合根(AR) 应如何相互通信?

例如,我有一个Facility聚合根 (AR),它有一个负责创建BookingAR 的工厂方法。这BookingPersonAR 和FacilityAR 的时间敏感组合。APerson只能单人预订Facility

在 DDD 中,我会持有对BookinginPersonPersonin的引用Facility。但是,在生成用于事件溯源的事件时,我认为尝试从后端处理事件反序列化会变得令人望而却步。因此,我只保留对基于值对象的唯一 ID 的引用。然而,这带来了一个新问题,当 AR 上的一个方法需要调用另一个 AR 上的另一个方法时——你如何处理这种情况?从域 AR 中访问事件源存储库?

这种情况下的一般用例是什么?我接近这一切都错了吗?

0 投票
4 回答
1007 浏览

c# - CQRS - 如何处理查看页面或查询的用户

我正在将 CQRS 用于我正在构建的应用程序(具有复杂业务逻辑的在线讨论系统),并且我在实现中遇到了让我担心的部分。

我应该如何处理综合浏览量?如果用户查看线程,我想跟踪它。因为我想跟踪它,所以我应该创建一个命令和一个事件,并将其绑定到负责我正在查看的对象的聚合根(例如,分别为 UserViewsThread 和 UserViewedThread)。但这似乎效率很低——除此之外,没有理由在讨论系统的许多用例(查看论坛/线程)中找到聚合根。现在我正在介绍这个,我将在页面的每个视图上都有一个额外的命令调度和事件发布,这反过来又负责“后台处理”线程聚合,序列化我的事件,并将其发送到我的事件出版商。

必须有更好的方法来做到这一点。我正在考虑也许让我的控制器对象能够调度事件 - 但是通过绕过我的聚合,我不能再将行为附加到页面浏览量。

另一种可能性是使用它作为验证我的用户的方式的想法。将允许 UserViewsThread 和 UserViewsForum 命令引发身份验证异常,让我的控制器知道用户无法执行此操作。但是,如果这些被翻译成事件,并存储在我的事件存储中,我们谈论的是在每个页面视图上创建的多个事件- 这很可能会破坏性能(每个页面视图都会导致数据库事务......呃)和资源管理。

你男朋友的想法是什么?

0 投票
2 回答
2020 浏览

domain-driven-design - 将 CQRS 和 DDD 与域事件和 ServiceBus 一起使用时在视图中显示更改

我对使用域事件构建读取模型的系统中的流程有点困惑。特别是,我们如何处理用户期望数据(及其视图)在他们完成命令时发生变化的事实,但由于我们的系统架构(发布事件的非阻塞调用),实际数据库可能不会在页面是否重新加载?

我希望使用事件和服务总线将我们其中一个系统的设计与 CQRS 更加内联。

假设我的流程是这样的:

  1. 用户单击视图中的按钮以执行从其帐户中删除付款方式的任务。

  2. 控制器调用 PaymentMethodRemovalService,将 accountId 和 paymentMethodId 传递给它。

  3. 控制器使用 AccountRepository 检索 Account 并调用 account.RemovePaymentMethod(id)

  4. 帐户验证可以发生操​​作并发布事件 PaymentMethodRemovedMessage(accountId, paymentMethodId)

  5. 因为事件发布是异步的,我们现在必须从服务返回并从控制器返回视图——但我们的实际数据还没有更新

  6. 处理程序 IHandle< PaymentMethodRemovedMessage > 听到事件并从数据库中删除实际行

那么,男人该怎么办?

我可以简单地说,删除显示付款方式的 div。这可能适用于 AJAX 场景,但如果我使用 Post-Redirect-Get 来支持非 JavaScript 客户端怎么办。然后我将触发我的 Get 并从 Query 端读取数据,可能在更新之前。

我是否只显示一条通知,说明他们删除付款方式的请求已提交?(这似乎并不友好,对于提交订单有意义,但对于更改地址则不然)。

有没有办法协调将更改实现为分离的异步事件并显示反映其当前更改的用户数据?

编辑:我的问题与CQRS、DDD 同步报告数据库非常相似, 我不得不说,那里给出的答案以及这里也提到的,有点味道 - 争吵 UI 以显示带外的更新可以这么说,读取数据库。我希望有一些更清洁的东西。

0 投票
3 回答
5488 浏览

domain-driven-design - 事件溯源和读取模型生成

假设堆栈溢出域问题和以下事件定义:

假设事件存储的状态如下(按出现顺序):

假设以下问题列表的非规范化阅读模型(对于 SO 的第一页):

以及以下事件处理程序(构建非规范化读取模型):

我的问题是如何找到提出问题的用户的姓名?或者更常见:如果我的非规范化读取模型需要特定事件中不存在的额外数据,我应该如何处理事件?

我检查了现有的 CQRS 样本,包括Greg Young的SimpleSQRS和 Mark Nijhof 的Fohjin样本。但在我看来,它们仅使用事件中包含的数据进行操作。

0 投票
1 回答
1494 浏览

cqrs - 如何处理读取模型与事件日志不同步的情况?

当聚合的快照与事件日志不同步时,我可以简单地从早期快照(应该是同步的)重播我的事件。当我添加/删除新字段或修改现有处理程序的逻辑时,我也可以这样做。

如果我需要添加新的读取模型(即新的报告视图),我可以再次执行相同的操作 - 我将重播我的事件。

但是,当读取模型与事件日志不同步时,我应该如何处理这种情况?事件的存储和发布在一个事务中,但读取模型的更新发生在另一个事务中,这可能会失败。从一开始就重复事件会有所帮助,但它可能需要永恒。我是否需要整个读取模型的快照概念?

你怎么解决这个问题?谢谢你。

0 投票
1 回答
565 浏览

cqrs - 事件溯源和字典对象

事件溯源如何与多种类型的字典对象(如CountryRegion等)Time Zone以及来自特定域模型(如BudgetAvailability定义)的字典类型相结合。一些字典对象应该可以在管理 UI 中编辑,但有些不能。

例如,我们决定不需要国家/地区的管理 UI。因此我们不需要执行AddCountry/RemoveCountry命令。

我应该生成一组CountryAdded事件,即我应该将字典对象作为事件流保存吗?除了事件流,我们是否曾经使用过事实来源?


如果我可以不用字典对象的事件流,你将如何解决这个问题:

显示国家列表以及每个国家的用户数量。

在这种情况下,我需要Country用事件监听器来表示读取模型中的对象UserAdded

谢谢你。

0 投票
5 回答
3427 浏览

cqrs - 准备视图模型时如何“加入”两个聚合根?

假设BookAuthor是我模型中的聚合根。

在阅读模型中,我有一个表格AuthorsAndBooks,它是作者和书籍的列表,由Book.AuthorId

触发事件时BookAdded,我想接收Author数据以创建新AuthorsAndBooks行。

因为Book是聚合根,事件Author中不包含有关的信息。BookAdded而且我不能包含它,因为Authorroot 没有吸气剂(根据所有示例和有关 CQRS 和事件溯源的帖子的指南)。

通常我会在这个问题上收到两种类型的答案:

  1. 使用事件处理程序中所需的所有数据丰富您的域事件。但正如我所说,我不能为聚合根做到这一点。
  2. 使用来自 View Model 的可用数据。即从视图模型加载Author并使用它来构建AuthorsAndBooks行。

最后一个在并发方面存在一些问题。BookAdded在处理事件时,视图模型中的作者数据可能不可用。

你用什么方法来解决这个问题?谢谢你。

0 投票
4 回答
3802 浏览

design-patterns - 如何在 CQRS + 事件溯源架构中管理 ViewModel 更改

我们目前正在评估 CQRS 和事件溯源架构。我试图了解使用这种设计的维护含义是什么。我正在努力寻找答案的两个问题是:

1) 如果在应用程序启动并运行了一段时间后,需要向 ReadModel 数据库上的 ViewModel 添加额外字段,会发生什么情况?比如说,在 CustomerList ViewModel 上需要客户邮政编码,而以前不需要。因此,可以轻松地将额外的列添加到 ViewModel 数据库中,但是如何填充呢?据我所知,唯一的方法是清除读取数据库,并从头开始重播所有事件以备份 ReadModel 数据库。但是,如果应用程序已经启动并运行了数月或数年(正如我们希望的那样)怎么办。这可能是要重播的数百万个事件,只是为邮政编码列添加数据。

如果出于某种技术原因,ReadModel 数据库不同步,或者我们想要添加一个新的 ReadModel 数据库,我也有同样的担忧。似乎应用程序越旧,使用得越多,获得最新的 readmodel 就越困难和昂贵。还是我在某个地方错过了一个技巧?ReadModel 快照之类的东西?

2) 如果在重播所有数百万个事件以备份读取数据库之后,一些数据与预期不符(即看起来错误),会发生什么情况。人们认为,可能是事件存储中的某个错误或非规范化例程可能导致了这种情况(似乎如果在编码中可以依赖一件事,那就是错误)。如何去调试这个!这似乎是一项不可能完成的任务。或者,也许,我又错过了一个窍门。

我很想听听任何已经运行这样的系统一段时间的人的意见,维护和升级路径是如何为您解决的。

感谢您的任何时间和投入。

0 投票
1 回答
1363 浏览

.net - CQRS + EventSourcing 可扩展性

我正在尝试在我的新项目中使用 CQRS 和 EventSorcing。我遵循 Greg Young 几年前建议的方式(Mark Nijhof 实施 - http://cre8ivethought.com/blog/2009/11/12/cqrs--la-greg-young/)。我有一些关于这个解决方案的可扩展性的问题。

这篇文章中提到了一些点Mark Nijhof 的文章。但现在的问题是 Denormalizer 部分,它负责更新报告数据库。这部分我想做异步,所以在将事件发布到总线后我想立即返回控制。我们建议可以将 Denormalizer 实现为独立的 Web 服务 (WCF),它将处理传入事件并使用批量命令以定时方式更新报告数据库。看起来它可能是一个瓶颈,所以我们还想在这一点上添加一些可扩展性 - 一个集群解决方案。但是在集群的情况下,我们无法控制报告数据库更新的顺序(或者我们应该实现一些奇怪的,我猜有错误的逻辑会检查报告数据库中的对象版本)。另一个问题是解决方案的可持续性:如果失败,我们将在非规范化器中丢失更新,只要我们不在任何地方持久化它们)。所以现在我正在寻找这个问题的解决方案(Denormalizer 可扩展性),欢迎提出任何想法!