TL;DR
複数のサービスにまたがる処理を、一連のローカルトランザクションとして調整するパターン。途中のステップが失敗したら、補償トランザクションで完了済みのステップの変更を取り消し、データの整合性を保つ。
なぜ必要か
マイクロサービスでは、サービスごとに専用のデータベースを持つことが多い。1 つのデータベースの中なら ACID の性質を保てるが、独立した複数のデータストアにまたがると、従来のデータベースの保証はそのまま使えない。サーガは、2 フェーズコミットのような分散トランザクションに頼らずに、サービス間のデータの整合性を保つ。
仕組み
各ローカルトランザクションは、1 つのサービスの中で処理をアトミックに終え、そのサービスのデータベースを更新する。そのあと、イベントやメッセージで次のトランザクションを始める。
実装の方法は 2 つある。
- コレオグラフィ: 中央の制御役を置かず、各サービスがイベントを発行し合って次の処理を起こす。サービスが少なく単純なワークフローに向く。ステップが増えると、どのサービスが何に反応するかを追いにくくなる
- オーケストレーション: 中央のオーケストレーターが各タスクの状態を持ち、参加するサービスに何をするかを指示する。複雑なワークフローに向くが、オーケストレーターが障害点になる。プロセスマネージャはこの役割にあたる
注意点
- 各サービスはデータベースへの変更をコミットしてしまうので、ロールバックはできない。取り消しは補償トランザクションで行う
- 補償トランザクションが必ず成功するとは限らない
- サービス間に分離がないので、更新の消失やダーティリードなどの異常が起こりうる
- 一時的な障害に備えて、各ステップをべき等にしておく必要がある