はじめに
システム開発部でバックエンドエンジニアをしている白坂です。
弊社では、『ドメイン駆動設計をはじめよう』の輪読会を行っています。
この記事では、第7章で扱われているイベント履歴式ドメインモデル(イベントソーシング)について自分の理解を整理します。
これからDDDを学ぶ方の参考になれば幸いです。
- はじめに
- 多くのシステムは「現在の状態」を保存する
- しかし業務では「過程」が重要
- 「状態」ではなく「出来事」を保存する
- 状態保存とイベント履歴式ドメインモデルの違い
- 現在の状態はどう扱うのか
- なぜこの持ち方をするのか
- イベント履歴から目的別のモデルを作れる
- イベントストアとは
- メリット
- デメリット
- まとめ
- 参考文献
多くのシステムは「現在の状態」を保存する
ECサイトの注文を例に考えます。
注文には次のような状態があります。
- 作成された
- 支払い待ち
- 支払い完了
- 発送済み
- キャンセル済み
一般的なシステムでは、注文は「現在のステータス」だけが管理され、それを更新していきます。
status = "SHIPPED"
この設計で分かるのは、今どうなっているかだけです。
しかし業務では「過程」が重要
ステータスが「発送済み」でも、
- キャンセルを試みた履歴があるか
- 決済に何回失敗したか
- 支払いが遅れたことがあるか
は分かりません。
つまり、状態は結果であり、そこに至る過程は表現されないということです。
業務改善や分析では、この「過程」が重要になります。
「状態」ではなく「出来事」を保存する
イベント履歴式ドメインモデルでは、状態そのものを保存する代わりに、起きた出来事(イベント)を記録します。
注文であれば、
- 注文が作成された
- 支払いが試みられた
- 支払いが完了した
- 注文が発送された
といったイベントを時系列で保存します。
状態保存とイベント履歴式ドメインモデルの違い
状態を保存する設計
| order_id | status | updated_at |
|---|---|---|
| 1001 | 発送完了 | 2026-01-01 12:00:00 |
この場合、保存されるのは現在の状態のみです。
イベント履歴式ドメインモデル
こちらは「現在の状態」を直接持ちません。
その代わりに、注文に対して起きたイベントの履歴を持ちます。
| order_id | event | timestamp |
|---|---|---|
| 1001 | 注文作成 | 2026-01-01 10:00:00 |
| 1001 | 支払い完了 | 2026-01-01 10:00:05 |
| 1001 | 発送完了 | 2026-01-01 12:00:00 |
持つのは状態ではなくイベントで、状態はイベントの履歴から再構築することができます。
現在の状態はどう扱うのか
イベントだけを保存する場合、現在の状態はどうやって分かるのかという疑問が出てきます。
イベント履歴式ドメインモデルでは、現在の状態はイベントを順に適用することで再構築します。
つまり、イベント履歴を読み込み、先頭から順に適用することで現在の状態を得ます。
実際のシステムでは、毎回すべてのイベントを適用するとコストが高い場合、
途中時点の状態を保存し、そこから先のイベントだけ適用する工夫が取られることもあります。
重要なのは、状態を保存しないことではなく、
イベント履歴をもとに状態を再構築する設計であることです。
なぜこの持ち方をするのか
理由は、業務では「過程」に意味があるからです。
- 支払いに何回失敗したか
- キャンセルが多いか
- どの操作がボトルネックか
こうした情報は、イベントの履歴がなければ把握できません。
イベント履歴式ドメインモデルならこのような業務理解を可能にします。
イベント履歴から目的別のモデルを作れる
イベント履歴をもとに状態を組み立てることで、
- 現在の注文状態を知る
- 過去のある時点の状態を再現する
ことができます。
さらに重要なのは、同じイベント履歴から目的に応じたモデルを作れることです。
例えば:
現在の状態を知るためのモデル
→ 今の注文状況を画面表示する検索しやすくするためのモデル
→ 過去の状態も含めて検索する業務分析のためのモデル
→ キャンセル率や支払い成功率を分析する
保存しているのはイベント履歴だけで、必要な情報はそこから構築します。
イベントストアとは
イベントを保存するデータベースをイベントストアと言います。
イベントストアの特徴
イベントストアは追記専用です。
保存済みイベントは更新・削除しません。
イベントは「過去の事実」として扱うためです。
メリット
過去の状態を再現できる
イベント履歴が残っているため、任意の時点の状態をあとから再現できます。
障害や不具合の調査で役立ちます。
業務の流れを詳しく把握できる
イベントは業務の出来事そのものなので
- どこで失敗が多いか
- どこで処理が滞りやすいか
といった傾向を把握しやすくなり、業務改善にもつながります。
履歴をそのまま監査に使える
イベントが時系列で残るため、操作履歴を正確に追えます。
金銭を扱うシステムでは特に相性が良いです。
同時更新の内容を見て判断できる
通常の楽観的排他制御は「更新があったかどうか」だけを見ます。
イベント履歴がある場合、
- どんな変更が追加されたのか
- それが業務的に問題のある変更か
まで確認できます。
そのため、通常の楽観的排他制御のようにすぐに処理を失敗させるのではなく、
追加されたイベントの内容を見て処理を判断する設計も可能になります。
デメリット
学習コストが高い
従来の設計に慣れていると理解に時間がかかります。
チーム全体の理解も必要になります。
イベント設計の変更が難しい
イベントは基本的に書き換えないため、設計ミスの影響が大きいです。
システムが複雑になりやすい
設計・運用ともに難易度が上がります。
そのため本書でも、正当な理由なく選択すべきではないとされています。
まとめ
イベント履歴式ドメインモデルは、状態ではなくイベントの履歴で集約を表現する設計です。
状態は結果であり、業務上重要なのはそこに至る過程です。
イベント履歴を持つことで、
- 過去の状態を再現できる
- 業務の流れを分析できる
- 監査やトラブル調査に活かせる
といったメリットがあります。
一方で、学習コストや設計の難しさもあるため、
常に採用すべき手法というわけではありません。
設計の選択肢の一つとして理解し、要件に応じてチームで検討していくことが重要だと感じました。
参考文献
Vlad Khononov 著、増田 亨、綿引 琢磨 訳
『ドメイン駆動設計をはじめよう ―ソフトウェアの実装と事業戦略を結びつける実践技法』
オライリー・ジャパン