概要
- マイクロサービスに移行する際にシステム移行に伴うDBの分解が発生した場合に、参照整合性の維持の為、分散トランザクションが選択肢に上がると思う。(上がらなければこの記事は読み飛ばしてください。)
- そんな分散トランザクションの危険性について、今回は記事にしていこうと思います。
データベーストランザクション
- 通常、データベーストランザクションについて考える時、このトランザクションが指すものとしてACIDトランザクションという概念があります。
ACIDトランザクション
- ACIDトランザクションとは、関連する複数の処理を一つとして管理するトランザクション処理に求められるジム・グレイが定義した4つの特性の概念です。
Atomicity(原子性/不可分性)
- トランザクションに含まれる個々の手順が「全て実行される」か、「全て失敗する」のどちらかの状態になることを保証します。
- その為、何かの理由で失敗した場合、操作全体が中断され、変更は行われなかったようになります。
Consistency(一貫性/整合性)
- データベースに変更が走った場合、トランザクションの前後でデータの整合性が保たれ、矛盾の無い状態が継続することで、データベースが有効で一貫性のある状態であることを保証します。
Isolation(分離性/独立性)
- トランザクション実行中の処理過程が外部から隠され、他の処理などに影響を与えないこと保証します。
- その為、複数のトランザクションが干渉することなく同時に動作できます。
Durability(永続性/耐久性)
- トランザクションが完了した場合、その結果は記録されシステム障害が発生してもデータが失われることがないことを保証します。
- また、データ記録中に障害などで中断した場合は、記録を元に更新を反映させるといった処理が行われます。
DB分割とトランザクジョン
- 下記に新しい顧客を登録するシステムの例にモノリスからサービスの移行とDBの分割したものを記載します。
- このシステムでは、顧客の登録が保留中から確認済みになった場合に、顧客テーブルの該当idのレコードのcolumnであるStatusを更新し、登録保留テーブルから該当idのレコードを削除します。
モノリス
- モノリスのシステムの場合は、下記のようにモノリスなシステムの場合、2つのトランザクションを1つのモノリスなシステムがそのトランザクションをコントロールできます。
マイクロサービス
- 下記にマイクロサービスに移行し、DBを分割し別のデータベースとした場合の図を示しました。
- この場合、それぞれの変更を別のデータベースで行われている為、2つのトランザクションを順序立て実行しなければならなくなります。
=> つまり、原子性が保証されなくなっていることを指します。
2フェーズコミット
- 上記のような複数のサービスに同時に行われる変更を可能にする方法として、2フェーズコミットという分散トランザクションの一般的なアルゴリズムがあります。
2フェーズコミットの仕組み
- 2フェーズコミットは、コミットを2段階に分けて行います。
第1フェーズ
- 第1フェーズでは、トランザクション処理を行うソフトウェア(コーディネータ)が、トランザクションに参加する全ワーカに問い合わせを行い、レコードの更新(コミット可能)かを確認します。
- なおこの時、レコードはローカルでロックされている状態にあります。
第2フェーズ
- 第2フェーズでは、全てコミット可能となれば、コーディネータは全ワーカに対してコミット処理を指示して、データの更新が行われます。
- ロックも解除されます。
欠点
2フェーズコミットには、下記のような欠点があります。
- 全てのコミットが正確に同じ時間に行われる保証はない。
- ロックを行うため、その調整が難しい。
- ワーカと関連するDBが増えた場合、システムの待ち時間も長くなり、システム全体のレイテンシーを低下させる恐れがある。
まとめ
- 以上のことより、マイクロサービスに移行した際に分散トランザクションを使用する選択肢が出た場合は、一度DBの設計を検討し直す(例えば、DBの分割を行わない等)、もしくは別の解決策を検討した方がいいです。