TL;DR

  • 基本は、1 つのトランザクションで 1 つの集約だけを更新する。
  • 2 つの口座間の送金のように、1 つのトランザクションで複数の集約を更新するケースもある。そのまま実装してもよいが、リファクタリングのきっかけになる。

内容

同じ境界づけられたコンテキストの中にある集約の間で、整合性をどう確保するかを考える。

一般的なルールは「1 つのトランザクションにつき 1 つの集約だけを更新する」である。複数の集約が同じ境界づけられたコンテキストにあっても、メッセージと結果整合性を使うべきである(異なるコンテキスト間での整合性)。

ただし、ワークフロー全体を 1 つのトランザクションと考えられる場合は、1 つのトランザクションで複数の集約を更新するのがよいこともある。典型的な例は 2 つの口座間の送金である。

Start transaction
Add X amount to accountA
Remove X amount to accountB
Commit transaction

口座が Account 集約で表されている場合、同じトランザクションで 2 つの集約を扱うことになる。これでも問題はないが、トランザクション自体が独自のアイデンティティを持つと考えられるので、リファクタリングのきっかけになる。

type MoneyTransfer = {
    Id: MoneyTransferId
    ToAccount: AccountId
    FromAccount: AccountId
    Amount: Money
}

キーワード

自分の理解

送金というトランザクションそのものをエンティティとして扱う、ということだと理解した。