概要
マイクロサービスでは、移行する際にシステム移行に伴うDBの分解が発生した場合に、分散トランザクションは推奨していません。参照: マイクロサービスに移行した際の分散トランザクションの危険性
簡単に説明するなら分散トランザクションは、不具合となる危険性がある為です。
そのため、マイクロサービスで複数のリソースの結果整合性を利用する方法として、Sagaパターンがあります。
Sagaパターンとは
Sagaパターンとは、結果整合性を使ったアーキテクチャの1つであり、複数の状態変更を調整できリソースを長時間ロックすることがないよう設計されたアーキテクチャパターンです。「Sagaの元々のアイデアは、Hector Garcia MolinaとKenneth Salemによって発表された論文から生まれました。」
もう少し詳しく説明すると、結果整合性を担保したい範囲を1つのローカルトランザクション(擬似的なトランザクション)と考えて処理を行います。これによって何がいいのかというと、複数にまたがるサービスごとでトランザクションを分解し、それぞれが独立で処理することで、1トランザクションあたりにかかる時間を短縮し、それによって複数行、テーブル全体を長時間ロックすることなく処理を実行できることがポイントです。
またSagaパターンでは、ロールバックを行わせようとした場合、単純なロールバックはできない(したら危険)ようになっています。なぜなら、Sagaパターンでは複数のトランザクションが関与しているため、途中で起こった障害から以前の状態に回復するためのロールバックをしようとした際に既にコミットされている可能性があります。
そのため、Sagaパターンでは、補償トランザクションという考え方で実装を行います。補償トランザクションとは、単純なロールバックを行うことができないので、代わり一連のトランザクションで実行した操作の逆向きにした取り消し操作によってロールバックを行います。
[各ローカルトランザクションとその操作で実行する責務を持つマイクロサービス例]
[トランザクション実行中エラーが起き、補償トランザクションが実行される例]
Sagaパターンの実装方法
Sagaパターンの実装方法として以下の2つあります。
- Choreography (コレオグラフィ)
- Orchestration (オーケストレーション)
Choreography (コレオグラフィ)
- コレオグラフィのSagaパターンでは、中央集権的な調整(コントローラ)の必要性を避けて、参加する要素がイベントを交換します。コレオグラフィを使用すると、他のサービスでローカルトランザクションをトリガーするイベントが、各ローカルトランザクションによって発行されます。
メリット
- sagaパターンに参加する要素全体に責任が分散されるため単一障害点がないです。
デメリット
- E2Eテストをする際にすべてのサービスが実行されている必要があるので、E2Eテストが難しくなる。
Orchestration (オーケストレーション)
- 中央集権的なコントローラ(オーケストレータ)が、どのローカルトランザクションを実行するかを、参加する要素に伝えます。 オーケストレーターは、すべてのトランザクションを処理します。また、オーケストレーターは、要求を実行するだけでなく、各タスクの状態に応じて、補正トランザクションを使って障害復旧も行います。
メリット
- プロセスのすべての参加する要素を制御することができます。
- 依存関係が明確なため、ビジネスロジックがシンプルです。
デメリット
- 設計が複雑になりやすく、調整するためのロジックを実装する必要があります。
- オーケストレータの管理対象がワークフローなので、障害点が発生します。