事务发件箱模式与事件溯源

use*_*719 8 design-patterns microservices

事务发件箱和事件溯源模式之间的确切区别是什么?两者都是竞争模式,可以用于相同的目的。有没有什么例子可以让我理解何时使用什么?

Ste*_*pUp 7

这两种模式都解决了如何可靠/原子地更新数据库和发送消息/事件的问题。

\n

所以区别就在于执行上。

\n

发件箱图案

\n
\n

在此方法中,域事件不会直接写入事件总线。\n相反,它会写入\n存储事件的服务的 \xe2\x80\x9coutbox\xe2\x80\x9d 角色中的表中它自己的数据库。然而,这里的关键点是在事件之前执行的事务和写入发件箱表的事件是同一事务的一部分。

\n
\n

事件溯源模式

\n
\n

事件溯源模式可以将所有事件按数据事件的顺序保存到数据库中。该事件数据库称为事件存储。它将每个更改附加到事件的顺序列表中,而不是更新数据记录的状态。

\n
\n


use*_*993 6

我发现这两个链接非常有用:

https://microservices.io/patterns/data/transactional-outbox.html https://microservices.io/patterns/data/event-commerce.html

它们都用于微服务环境中,以保证不同微服务和数据库之间的一致性,而无需使用两阶段提交(2PC)

事务发件箱模式允许您在数据库中采用传统的实体设计,并且对实体执行的每个更新操作实际上都会更新数据库中的某些行。该模式还需要使用数据库中的发件箱表,以便您可以拥有一个本地事务

  • 更新数据库
  • 在发件箱表中创建消息条目

然后使用消息中继读取发件箱表并将消息发送到代理

使用事件溯源模式的数据库设计结果与传统设计略有不同。

考虑一个具有以下属性的帐户实体:

  • id(字符串)
  • 信用(数量)

假设您有一个 Account 表,如下所示:

| Id       | Credit |
| account1 | 5      |
Run Code Online (Sandbox Code Playgroud)

如果您执行更新操作,将信用值加 1,则会以下列方式影响表:

| Id       | Credit |
| account1 | 6      |
Run Code Online (Sandbox Code Playgroud)

使用事件源模式,您不会将帐户直接存储在数据库中,而是存储帐户上发生的交易:

| TransactionType   | AccountId | Credit |
| Create            | account1  | 5      |
| Add               | account1  | 1      |
Run Code Online (Sandbox Code Playgroud)

由于这种方法的读取操作有点复杂(您应该对所有行进行求和并减去每个事务的信用以获得当前信用),因此它通常与 CQRS 模式一起使用