このパターンを使用して、最終的に一貫性のある操作で 1 つ以上の手順が失敗した場合に作業を元に戻します。 複雑なビジネス プロセスとワークフローを実装するクラウドでホストされるアプリケーションでは、通常、最終的な整合性モデルに従う操作が使用されます。
コンテキストと問題
クラウド アプリケーションは、さまざまな地理的な場所にあるさまざまなデータ ソースに分散するデータを頻繁に変更します。 分散環境での競合を回避し、パフォーマンスを向上させるには、アプリケーションは強力なトランザクション整合性ではなく最終的な整合性を実装する必要があります。 最終的整合性モデルでは、一般的なビジネス操作は一連の独立したステップで構成されます。 これらの手順では、システム状態の全体的なビューに一貫性がない可能性があります。 しかし、すべてのステップが完了すると、システムは再び一貫性を保つ必要があります。
ステップエラーの処理は、最終的な整合性モデルにおいて重要な課題となります。 エラーが発生した後、完了した操作手順から作業を元に戻すことが必要になる場合があります。 ただし、他の同時実行アプリケーション インスタンスによってデータが変更される可能性があるため、常にデータをロールバックできるわけではありません。 同時実行インスタンスがデータを変更しない場合でも、元の状態を復元するよりも、ステップを元に戻す方が複雑になる場合があります。 ビジネス固有のルールを適用することが必要な場合があります。 例については、 旅行 Web サイトの例を参照してください。
最終的な整合性を実装する操作が複数のデータ ストアにまたがる場合は、各データ ストアにアクセスして変更を元に戻す必要があります。 システムに不整合が残らないようにするには、すべてのデータ ストアの作業を確実に元に戻す必要があります。
最終的な整合性を実装する操作では、影響を受けるデータが常にデータベースに格納されるとは限りません。 たとえば、サービス指向アーキテクチャ (SOA) 環境では、操作でサービス内のアクションを呼び出し、サービスが保持する状態を変更できます。 操作を元に戻すには、この状態変更を元に戻す必要もあります。この変更には、サービスを再度呼び出して最初のアクションの効果を元に戻す必要があります。
ソリューション
元の操作で完了したステップの影響を元に戻す補正トランザクションを実装します。 システムを元の状態に復元するだけで済むと思われるかもしれませんが、この方法では、他の同時実行アプリケーション インスタンスからの変更を上書きできます。 代わりに、補正トランザクションは同時作業をインテリジェントに考慮する必要があります。 通常、このプロセスはアプリケーション固有であり、元の操作に依存します。
ワークフローを使用して、補正を必要とする最終的に一貫性のある操作を実装できます。 元の操作が実行されると、各ステップとその取り消し方法に関する情報が記録されます。 操作が失敗した場合、ワークフローは完了したステップを巻き戻し、各ステップを元に戻します。
各ステップは個別のアクションですが、一緒に最終的に一貫性のある操作を形成します。 各ステップに対する操作と、対応する元に戻す操作を実行する必要があります。 顧客が取り消した場合、これらの元に戻す操作は補正トランザクションとして実行できます。
単一ステップの障害では、補正トランザクションを使用してシステム全体をロールバックする必要はありません。 たとえば、旅行 Web サイトのシナリオでは、顧客はフライト F1、F2、F3 を予約しますが、ホテル H1 で部屋を予約できません。 フライトをキャンセルする場合は、お客様に別のホテルの客室を提供することをお勧めしています。 顧客は引き続きキャンセルを選択できます。この場合、補正トランザクションがトリガーされ、フライトの予約が元に戻されます。 ただし、お客様はシステムではなく、この決定を行う必要があります。 意思決定が大きな影響を受ける場合や、確実に自動化するのが難しい場合は、意思決定プロセスに人間を含めます。
次の重要な点を考慮してください。
補正トランザクションでは、元の操作の正確な逆の順序で作業を元に戻す必要がない場合があります。
一部の元に戻す手順を並列で実行できる場合があります。
ビジネス固有のルールを適用することが必要な場合があります。 たとえば、フライト予約をキャンセルしても、顧客が払い戻しを全額受け取れない場合があります。
この方法は、 Saga 分散トランザクション パターンに似ています。
補正トランザクションは最終的に一貫性のある操作であり、失敗する可能性があります。 システムは、障害発生時点から補正トランザクションを再開できるように、進行状況を記録する必要があります。 再試行するとステップが複数回実行される可能性があるため、各ステップを べき等コマンドとして設計します。
場合によっては、手動による介入が、失敗した手順から回復する唯一の方法です。 このような状況では、システムはエラーの理由に関する詳細情報を含むアラートを生成する必要があります。
問題と考慮事項
このパターンを実装する方法を決定するときは、次の点を考慮してください。
最終的整合性を実装する操作内のステップがいつ失敗したのかを容易に判断できない場合があります。 ステップはすぐに失敗せず、代わりにブロックされる可能性があります。 タイムアウト メカニズムの実装が必要になる場合があります。
補正ロジックは簡単に一般化できません。 補正トランザクションはアプリケーション固有です。 失敗した操作の各ステップの影響を元に戻すための十分な情報をアプリケーションに依存します。
補正トランザクションは常に機能するとは限りません。 補正トランザクション自体が失敗した場合に備えて、補正トランザクションの各ステップをべき等なコマンドとして定義し、再実行可能にします。
ステップを処理するインフラストラクチャは、次の条件を満たしている必要があります。
元の操作と補正トランザクションの両方で回復性があります。
失敗した手順を補うために必要な情報は失われません。
補正ロジックの進行状況を確実に監視します。 補正トランザクションは、元の操作のコミット後に実行され、他のトランザクションによって中間状態が変更される可能性があります。 そのため、元の操作とその補正の両方をエンド ツー エンドで関連付け、監査できることを確認します。
補正トランザクションでは、システムのデータを必ずしも元の操作の開始時の状態に戻すわけではありません。 代わりに、トランザクションは、操作が失敗する前に正常に完了した作業を補正します。
補正トランザクションの手順では、元の操作が必ずしも正確に逆の順序で行われるとは限りません。 たとえば、あるデータ ストアが他のデータ ストアよりも不整合の影響を受けやすい場合は、まずそのストアに対する変更を元に戻します。
いくつかの対策は、成功率を向上させるのに役立ちます。 操作を完了するために必要な各リソースに、タイムアウトを含む短期的なロックを設定できます。 これらのリソースは事前に取得し、すべてのリソースを取得した後にのみ作業を実行できます。 ロックの期限が切れる前にすべてのアクションを終了します。
より多くのエラーを一時的なものとして扱う再試行ロジックは、補正トランザクションをトリガーするエラーを最小限に抑えるのに役立ちます。 最終的な整合性を実装する操作のステップが失敗した場合は、一時的な例外として処理し、手順を再試行します。 操作を停止し、ステップが繰り返し失敗した場合、または復旧できない場合にのみ補正をトリガーします。 再試行戦略の詳細については、「 一時的な障害処理」を参照してください。
補正トランザクションを実装すると、最終的な整合性の実装と同様に、多くの課題に直面します。 詳細については、「調整の 最小化」を参照してください。
戻り値のないステップと元に戻せないステップの明確なポイントを定義します。 複雑なワークフローでは、外部の副作用や法的拘束力のあるアクションなど、一部の操作を安全または意味のある方法で元に戻すことはできません。 互換性のないステップと元に戻せないステップを特定します。 すべての重要な検証が成功した後にのみ元に戻せない手順が実行されるようにワークフローを設計します。
このパターンを使用する場合
このパターンは次の状況で使用します。
ビジネス操作は複数のステップ、サービス、またはデータ ストアにまたがるので、後の手順で失敗した場合は元に戻す必要があります。 このシナリオは、多くの場合、最終的な整合性モデルに従い、アトミック トランザクションに依存できない、実行時間の長いワークフローで発生します。
障害復旧には、多くの場合、単純なデータロールバックではなく、ドメイン固有のロジックが必要です。 作業を元に戻すときに補正アクションを使用するには、予約の取り消しや一部払い戻しの発行などのビジネス ルールを適用する必要があります。
このパターンは、次の場合に適さない場合があります。
操作は安全に再試行でき、ほとんどのエラーは一時的なものです。 多くの場合、再試行ロジックだけでは十分であり、補正トランザクションは不要な複雑さを増します。
システムは一時的な不整合を許容できないか、補正によって有効な状態を確実に復元できません。 代わりに、すべての手順で強力な整合性メカニズムまたはアトミック トランザクションを使用します。
ワークロード設計
ワークロードの設計で補正トランザクションを使用して、Azure Well-Architected Framework の柱で説明されている目標と原則に対処する方法を評価します。 次の表は、このパターンが各柱の目標をサポートする方法に関するガイダンスを示しています。
| 支柱 | このパターンが柱の目標をサポートする方法 |
|---|---|
| 信頼性設計の決定は、故障に対するワークロードの回復性を高め、障害の発生後にワークロードを完全な機能状態に回復させるために役立ちます。 | 補正アクションは、データ変更を直接ロールバックしたり、トランザクション ロックを解除したり、ネイティブ システムの動作を実行して効果を元に戻したりするなどのプロセスを使用して、重要なワークロード パスの誤動作に対処します。 - RE:02 重要な流れ - RE:09 災害復旧 |
このパターンによって柱内にトレードオフが生じる場合は、他の柱の目標に照らして検討してください。
例
次の図は、補正トランザクション パターンの実用的なAzure実装を示しています。 その他の実装は、ワークロードの要件にも適している場合があります。 Azure Container Appsで実行されるオーケストレーターは、Azure Service Busを介してコマンドを送信することで、実行時間の長いワークフローの各ステップを調整します。 各前進ステップが成功すると、オーケストレーターは、ワークフローを再開、関連付け、監査できるように、実行状態と対応する補正アクションの両方をAzure Cosmos DBに記録します。
このモデルでは、最初に再試行を使用して、前方の進行状況を保持します。 ステップが失敗した場合、オーケストレーターは一時的な障害に対して再試行ロジックを適用し、元の操作を続行しようとします。 補正は、再試行が使い果たされたり、失敗が非一時的として分類されたりする場合など、前方進行が不可能になった場合にのみ呼び出されます。
また、ビジネス固有のルールは、即時の報酬よりも前方進行を優先することもできます。 ステップが失敗した場合、オーケストレーターは、ワークフローをロールバックする代わりに、同等のサービスやフォールバック オプションを置き換えるなどの代替パスを選択できます。 影響が大きい場合やあいまいな場合は、代替パスで続行するか補正をトリガーするかを決定する前に、ヒューマン レビューのワークフローを一時停止できます。 このアプローチでは、補正が最後の手段として扱われ、ドメイン ルールによって回復の決定が促進されます。
一般的なシーケンスでは、オーケストレーターはService Bus (手順 1 と 2) を通じてステップ メッセージを送信し、成功した結果を受け取り、前方メタデータと補正メタデータをAzure Cosmos DBに格納します。
補正は、次の 2 つの方法でトリガーできます。
同じワークロードの後の手順が失敗し、以前に成功した手順を元に戻す必要がある場合。 この補正は、ルール検証の失敗などのビジネス エラーがステップから返されたり、技術的な再試行が使い果たされ、メッセージが配信不能キューに移動されたりすると、すぐに発生する可能性があります。
後続のクライアントが、完了した操作の取り消しを明示的に要求した場合。
いずれの場合も、オーケストレーターは、格納されている補正レコードを読み取り、対応するサービスに補正コマンドを送信します。 補正ステップが一時的に失敗した場合、Service Bus再試行はインシデントをエスカレートせずに完了できます。
再試行を繰り返しても失敗する場合は、Service Busメッセージを配信不能キューに移動し、エラーの詳細を保持します。 オーケストレーター、または専用のデッドレタープロセッサは、アラートを生成して通知し、失敗理由や関連付けIDを含む構造化テレメトリをAzure MonitorおよびLog Analyticsに出力します。このテレメトリはApplication Insightsに表示される可能性があります。 この運用パスは、チームが障害を診断し、手動介入の必要性を判断し、元のフローと補正フローの両方で追跡可能性を維持するのに役立ちます。
ワークフローは、明確でリスクの低い条件に対して自動的に補正を開始したり、状況があいまいで、影響が大きい場合、または手動で決定する必要がある場合に、ヒューマン レビューのために一時停止したりできます。
共有シークレットを回避し、最小特権アクセスを適用するには、マネージド ID とコンポーネント間のMicrosoft Entra IDベースの承認を使用します。 簡略化された参照図を作成する場合は、明示的なフロー ステップではなく、これらの ID と承認の制御をベースライン実装の問題として扱います。 図は、オーケストレーション、再試行、補正、およびエラー処理に重点を置いたままにします。
関連するリソース
マイクロサービスのデータに関する考慮事項: 最終的な整合性と部分的な障害が分散システムに固有である理由について説明します。 補正トランザクション パターンは、操作が複数のサービスにまたがる場合にこれらのエラーを処理するための具体的なメカニズムを提供します。
Azure Cosmos DB を使用したトランザクショナル・アウトボックス・パターン: 補正トランザクションでイベントまたはコマンドを確実に発行する必要がある場合は、このパターンを使用します。 これにより、状態の変更とメッセージがアトミックに記録され、メッセージの損失を防ぐことができます。
自己復旧のための設計: アプリケーションの自己復旧アプローチの一部として補正トランザクションを使用します。
Scheduler Agent Supervisor パターン: このパターンを使用して、分散サービスとリソース間でビジネス操作を実行する回復性のあるシステムを実装します。 これらのシステムでは、作業を元に戻すために補正トランザクションが必要な場合があります。
再試行パターン: このパターンを使用して、一時的な障害を処理し、補正トランザクションの必要性を最小限に抑えます。
Saga 分散トランザクション パターン: このパターンを使用して、分散トランザクション内のマイクロサービス間のデータ整合性を管理します。 Saga では、障害復旧に補正トランザクションを使用します。
パイプとフィルター パターン: 複雑なタスクを再利用可能な手順に分解する場合は、分散トランザクションの代わりに、このパターンを補正トランザクション パターンと共に使用します。