1.3 分散トランザクション・プロトコルについて

MicroTxでは、次の分散トランザクション・プロトコルがサポートされています:

XAを使用するのは、ローカル・データベース・トランザクションによって提供される一貫性のように強力な一貫性が必要な場合です。これにはトランザクションのすべてのACIDプロパティが存在します。たとえば、財務アプリケーションです。LRAプロトコルを使用するのは、完了に時間がかかる可能性があるトランザクションの場合です。LRAプロトコルを使用すると、ロックの問題を軽減できます。TCCプロトコルは、飛行機座席やホテル客室などの予約モデルを使用するアプリケーションに適しています。LRAとTCCはどちらも長時間実行トランザクションをサポートしています。LRAの方が一般的ですが、成功したLRAの完了と失敗したLRAの補正のために、アプリケーション固有のアクションが必要です。一方、TCCでの補正は、予約を削除してから予約されていたものを使用可能リソースのプールに返すことによって実行されます。

1.3.1 XAトランザクション・プロトコル

XAを使用するアプリケーションは、トランザクションの境界を設定する必要があります。MicroTxがトランザクションをコミットまたはロールバックします。

XAプロトコルで、参加側マイクロサービスは、MicroTxクライアント・ライブラリを使用する必要があります。これが、コールバックを登録して、リソース・マネージャのためにコールバックの実装を提供します。次の図に示すように、MicroTxはリソース・マネージャと通信して、トランザクションをコミットまたはロールバックします。MicroTxは、トランザクションに関係する各リソース・マネージャに接続して、トランザクションを準備、コミットまたはロールバックします。参加側サービスは、リソース・マネージャにアクセスするための資格証明をコーディネータに提供します。次の図に示すように、MicroTxクライアント・ライブラリによってリソース・マネージャ・プロキシ(RMプロキシ)が提供されます。このプロキシにより、コーディネータがリソース・マネージャ固有のライブラリを保持する必要がなくなります。これはXAでは通常のケースです。トランザクション・コーディネータが、参加側のリソース・マネージャのために、トランザクションの準備、コミットまたはロールバックを行う必要がある場合は、マイクロサービスにコールバックを行います。さらに、プロキシが、そのマイクロサービスによって使用されているリソース・マネージャにリクエストをリレーします。このようなRESTベースのコールバックにより、トランザクション・コーディネータが、マイクロサービスで使用されるリソース・マネージャの影響を受けなくなります。

クライアント・ライブラリおよびRMプロキシの役割
  1. イニシエータが分散トランザクションを開始します
  2. コールされたマイクロサービスがトランザクションに登録されます
  3. イニシエータが、トランザクション・マネージャにトランザクションのコミットまたはロールバックを依頼します
  4. イニシエータがコミットを決定した場合、トランザクション・マネージャは各マイクロサービスに準備を依頼します
    1. すべての参加側の準備が正常に行われると、すべての参加側がコミットを依頼されます
    2. いずれかの参加側の準備が失敗すると、すべての参加側がロールバックを依頼されます
  5. イニシエータがロールバックを決定した場合、トランザクション・マネージャは各マイクロサービスにロールバックを依頼します
マイクロサービス、MicroTxクライアント・ライブラリ、およびコーディネータの間で通信がどのように行われるかを理解するには、「XAサンプル・アプリケーションについて」を参照してください。

1.3.2 LRAトランザクション・プロトコル

次の図は、Eclipse MicroProfile Long Running Actions (LRA)トランザクション・プロトコルを使用するときに、どのようにマイクロサービスが相互に通信したりMicroTxと通信したりするかを示しています。

LRAトランザクション・プロトコルを使用するマイクロサービス

マイクロサービスが相互に通信してサンプル・トランザクションを処理する方法を説明します。

  1. トランザクション・イニシエータ・サービスは、MicroTx LRAコーディネータをコールし、LRAトランザクションを開始してそれに登録するためのコールバックURIを渡します。
  2. トランザクション・イニシエータ・サービスは、ヘッダーでLRAのIDを渡して、1つ以上の参加側サービスを呼び出します。
  3. 他の参加側サービスはMicroTxをコールし、LRAトランザクションに登録または参加します。参加側がLRAに参加するとき、コールバックURIを提供しますが、これにはLRA内の担当部分を完了したり補正したりするものが含まれます。
  4. トランザクション・イニシエータ・サービスは、MicroTxをコールして、トランザクションを完了または補正します。
  5. MicroTxは、トランザクション・イニシエータ・サービスがトランザクションの完了と補正のどちらを要求するかに応じて、各参加側サービスの完了コールバックURIまたは補正コールバックURIをコールします。

各参加側は、相互に独立したローカル・トランザクションを使用します。LRAトランザクション・プロトコルはローカル・トランザクションを使用するため、システム全体では状態が矛盾する期間がありますが、トランザクションの目的はトランザクションの最後に一貫性を実現することです。これは、ローカル・トランザクションが個別に完了または補正されるためです。つまり、1つ以上のローカル・トランザクションが完了または補正されても、他のトランザクションが完了していない時期があります。ロックや分離が行われないため、他のシステムまたはユーザーがこのように一貫性のない状態を認識する場合があり、一貫性のない状態に基づいて誤った決定を行う可能性があります。

1.3.3 Try-Confirm/Cancelトランザクション・プロトコル

Try-Confirm/Cancel (TCC)トランザクション・プロトコルは、トランザクションが確定されるか取り消されるまで、リソースを予約状態のまま保持します。トランザクションが取り消されると、予約されたリソースが解放され、インベントリで使用できるようになります。

TCCトランザクション・プロトコルは、基本のHTTP動詞(POSTPUTおよびDELETE)に依存します。アプリケーションが次のガイドラインに準拠していることを確認します:

  • トランザクション・イニシエータ・サービスは、POST HTTPメソッドを使用して新しい予約を作成する必要があります。このリクエストへのレスポンスとして、トランザクション参加側サービスは予約を表すURIを返す必要があります。MicroTxクライアント・ライブラリは、MicroTx固有のヘッダーにそのURIを配置して、URIがコール・スタックに伝播されるようにします。
  • このプロトコルは参加側サービスに依存して、確実にすべての参加側サービスが予約を確定するか取り消すようにします。URIは、予約を確定するためにPUT HTTPメソッドに応答し、予約を取り消すにはDELETE HTTPメソッドに応答する必要があります。

次の図は、TCCトランザクションでマイクロサービスとMicroTxが相互に作用する仕組みを示しています。

1つのトランザクションでXおよびYを予約するために、様々なコンポーネントが相互に作用する仕組み。

マイクロサービスAはトランザクション・イニシエータ・サービスです。トランザクションを開始して終了させます。トランザクションに参加側サービスを含める必要があることを示すリクエストを参加側サービスに送信します。

マイクロサービスBおよびCは参加側サービスです。これらのサービスは、既存のトランザクションに参加するだけです。トランザクションを開始することはありません。

試行フェーズ

TCCプロトコルでは、トランザクション・イニシエータ・サービスが、他の参加側マイクロサービスにリソースを予約するように求めます。試行フェーズで、MicroTxライブラリは、受け入れたすべての予約を収集します。これには、参加側サービスによって行われた予約が含まれます。イニシエータ(上にある例の図のマイクロサービスA)がマイクロサービスBとマイクロサービスCに対して予約を完了するまで、MicroTxライブラリがすべての予約を収集します。その時点で、イニシエータは、予約の確定、取消または無視を決定できます(無視した場合、タイムアウトによって最終的に予約が取り消されます)。

確定/取消フェーズ

イニシエータ・サービスに指定されているビジネス・ロジックに基づいて、すべての予約を確定するか、すべての予約を取り消すかを決定できます。イニシエータとすべての参加側が必要な予約を取得すると、イニシエータ・サービスは、すべての予約を確定するようにMicroTxにリクエストを送信します。イニシエータ・サービスがビジネス・ロジックに基づいて、行われた予約が必要ない(使用できない)と判断すると、すべての予約を取り消すようにMicroTxにリクエストします。予約の内容はアプリケーションによって異なります。

公演の座席を予約して購入するためのシンプルなマイクロサービスについて考えてみましょう。座席の状態は、AVAILABLERESERVEDSOLDのいずれかになります。試行フェーズでは、座席の状態がAVAILABLEからRESERVEDに変更されます。確定フェーズでは、支払が正常に完了したことを前提として、状態がRESERVEDからSOLDに変更されます。取消フェーズでは、状態がRESERVEDからAVAILABLEに変更されます。支払が正常に完了しなかった場合の確定ステップのエラーを防ぐために、試行フェーズでは、マイクロサービスは支払が確実に行われるように支払承認を取得する必要があります。

アプリケーションが特定の数量(在庫の品目や口座の資金など)を予約する別の例について考えてみましょう。このケースでは、試行フェーズで、使用可能な数量から予約した数量を差し引き、予約のレコードがデータベースに追加されます。確定フェーズでは、予約レコードが削除されます。取消フェーズでは、予約レコードの数量が在庫数量に戻され、予約レコードが削除されます。

次のステップで、マイクロサービスとMicroTxを含むTCCトランザクションの正常なパスを示します。エラー時には、イニシエータ・サービスが確定のかわりに取消をコールします。

  1. トランザクション・イニシエータ・サービスであるマイクロサービスAが、MicroTxクライアント・ライブラリ・コールを行ってTCCトランザクションを開始します。
  2. トランザクション・イニシエータ・サービスは、参加側サービスであるマイクロサービスBでPOSTを呼び出して、リソースXを予約します。
  3. マイクロサービスBは、必要なリソースを予約し、その予約を表すURIをトランザクション・イニシエータであるマイクロサービスAに返します。
  4. トランザクション・イニシエータ・サービスは、参加側サービスであるマイクロサービスCでPOSTを呼び出して、リソースYを予約します。
  5. マイクロサービスCは、必要なリソースを予約し、その予約を表すURIをトランザクション・イニシエータであるマイクロサービスAに返します。
  6. マイクロサービスA (トランザクション・イニシエータ・サービス)が、MicroTxをコールして、予約を確定するか取り消します。
  7. MicroTxが、PUTをコールして確定するか、DELETEをコールしてすべてのURI (予約)を取り消し、トランザクションを完了します。
  8. 参加側サービスはリソースを確定するか取り消してから、HTTPレスポンス・コード200MicroTxに返します。
  9. MicroTxは、トランザクション・イニシエータであるマイクロサービスAに正常を示すステータスを返します。MicroTxが、1つ以上の参加側から200ステータスを受信しない場合は、エラー・メッセージを返します。