B2B Commerce CloudにおけるチェックアウトフローとSaga

前書き

B2B Commerce Cloudにおけるチェックアウトフローは、各フローの実行順序を中央のコーディネーターで制御するオーケストレーションベースのサーガ(orchestration-based saga)の一種である。

本記事では、こうしたオーケストレーションベースのサーガがDBに対する通常のトランザクションと比べてどのような相違・特徴があるのかについて考えていきたい。

↓下記の図から明らかなように、B2BCCのチェックアウトフローの各処理の順序やステータスは中央のハブにより制御されている。

一般的なデータベーストランザクション

一般的なデータベーストランザクションは、ACIDトランザクションである。すなわち、下記の四つの特性を満たす。

Atomicity(原子性):トランザクション内の操作が、全て完了か全て失敗のいずれかであること。すなわち、何らかの理由で特定の操作に失敗した場合、操作全体が中断され、全体の操作がなかったことになること。

Consistency(一貫性):データベースに変更が加えられた場合に、(そのトランザクションの終了状態に関わらず)データベースの整合性が保たれていること

Isolation(独立性):複数のトランザクションが干渉することなく同時に動作すること。

Durability(耐久性):トランザクションが完了すると、システム障害が発生しても更新内容が失われることがないこと。

問題は、複数スキーマの同時変更やLLTにおいてACIDの特性をどのようにして満たすのかという点にある。

複数のテーブルを同時にUPDATEする処理において、どれか一つの処理が失敗した場合に全てのUPDATE処理をロールバックする仕組みがなければ「Atomicity(原子性)」が崩壊し、ひいては「Consistency(一貫性)」も崩壊してしまう。

同様に、LLTの後半で処理が失敗した場合に以前の変更をロールバックする仕組みがなければ「Atomicity(原子性)」と「Consistency(一貫性)」の双方が崩壊してしまう。

2フェーズコミット

■前書き

複数スキーマの同時変更時に原子性が崩れてしまう問題への代表的な対応策が、2フェーズコミットに代表される分散トランザクションである。

■概要

コーディネーターがDBをラップしている各サービスに対して①処理の可否を伺い(投票フェーズ)②問題がなければコミットを行う(コミットフェーズ)(※つまるところ、3wayハンドシェイクと同じ)

■pros

投票フェーズの結果に応じて、全トランザクションをロールバックすることができる。

■cons

投票時にOKを返したのにコミット時に応答がないDBが一つでもあると、特定のDBにコミットが行われ、特定のDBにはコミットが行われていない状態となり「Atomicity(原子性)」が崩壊する。また、投票後にコーディネーターからコミット指示が来ない場合、データベースに永遠にロックがかかり続ける。

■2フェーズコミットを利用しない場合

■2フェーズコミット

Saga

■前書き

2フェーズコミットのconsに挙げたような問題を解決し得るのが、サーガ(Saga)である。

■概要

サーガ(Saga)とは「複数の状態変更を調整でき、[2フェーズコミットのように]リソースを長時間ロックする必要がないようにでデザインされたアルゴリズム(194頁)」のこと。元来は、トランザクション全体の処理に数分~数時間を要するLLT(Long-lived Transactions)複数のサブトランザクションに分割することで、ロックの範囲と時間の大幅な削減を実現する仕組みとして考案された。

■サーガにおける障害回復

サーガの障害回復には一般に後方回復と前方回復が存在する。後方回復とは、障害発生時のロールバックを意味する。後方回復の実現には、過去にコミット済みのトランザクションを元に戻すための何らかの補償アクションが必要となる。前方回復は、障害発生後に障害が発生したポイントから処理を継続できることを意味する。前方回復の実現には、処理継続のために必要な情報を保持しておくことが必要となる。

B2B Commerce Cloudチェックアウトフローにおける後方回復と補償アクション

B2B Commerce Cloudのチェックアウトフローのカスタマイズの一つのポイントは、後方回復における補償トランザクション(Compensating Transaction)を可能な限り不要にすることにある。それはすなわち以下の方針に基づいてカスタマイズ方針が決定されるべきことを意味する。

  1. チェックアウトフローの途中に外部DBに変更を加えるような処理を可能な限り挟まないようにすること
  2. もし外部DBに変更を加えるような処理がある場合は、そのコミット処理をチェックアウトフローの可能な限り後方に配置すること

例えば、「在庫の仮引当」のような処理は、可能な限りチェックアウトフローに組み込むべきではないし、「Activate Order」のようなDBへのコミットを伴うサブフローは可能な限りチェックアウトフローの後方に配置されるべきである。

サーガの実装

■概要

サーガ(Saga)の実装にはオーケストレーションベースのサーガとコレオグラフィベースのサーガという大きく二つのスタイルがあり得る。オーケストレーションベースのサーガにおいては、中央のコーディネーター(ないしオーケストレーター)が個別の処理の実行順序と補償アクションをコントロールする。一方、コレオグラフィベースのサーガにおいては、異なるサービスがイベントをブロードキャストし、その他のシステムがそのイベントを受信し処理を行うという組み合わせによって全体のプロセスが形成される。

■オーケストレーションベースのサーガのprosとcons

pros:構成が極めて簡潔なものとなる

cons:①一定のドメイン結合が発生する②サービスに実装されるべきロジックの一部が中央のコーディネーターに吸収される(ロジックが中央に集約する)リスクが存在する

■コレオグラフィベースのサーガのprosとcons

pros:①結合が少ない②ロジックが中央に集約するリスクがないため、各ロジックは必ず各サービスに実装される

cons:①構成が極めて複雑なものとなり得る②サーガの現在の状態(ステータス)を保持する場所が存在しないため、前方回復が困難になる(※これを回避するためにはサーガの現在の状態を保存するテーブルを用意する必要がある。)

参考

サム・ニューマン著,島田浩二訳 (2003) 『モノリスからマイクロサービスへ』,株式会社オライリー・ジャパン.

Other

Posted by regardie