2フェーズコミットについて
2フェーズコミットは、分散トランザクションが失敗しないことを保証するものではありませんが、TMが認識しない限りサイレントに失敗しないことを保証します。
Bがトランザクションをコミットの準備ができていると報告するには、Bはトランザクションを永続ストレージに保持する必要があります(つまり、Bは、トランザクションがすべての状況でコミットできることを保証できる必要があります)。この状況では、Bはトランザクションを永続化していますが、トランザクションマネージャーはBからコミットを完了したことを確認するメッセージをまだ受信していません。
トランザクションマネージャは、Bがオンラインに戻ったときに、Bを再度ポーリングし、トランザクションをコミットするように要求します。Bがすでにトランザクションをコミットしている場合は、トランザクションがコミット済みとして報告されます。Bがまだトランザクションをコミットしていない場合は、すでに永続化されているためコミットし、トランザクションをコミットする立場にあります。
この状況でBが失敗するためには、データまたはログエントリを失うという壊滅的な障害が発生する必要があります。トランザクションマネージャは、Bがコミットの成功を報告しなかったことを認識します。1
実際には、Bがトランザクションをコミットできなくなった場合、Bを取り除いた災害によってデータが失われたことを意味し、TMが認識していないTxIDをコミットするように要求したときに、Bはエラーを報告します。コミット可能な状態にあるとは思わなかった。
したがって、2フェーズ・コミットは、壊滅的な障害の発生を防ぐことはできませんが、障害が見過ごされることを防ぎます。このシナリオでは、Bがコミットできない場合、トランザクションマネージャーはアプリケーションにエラーを報告します。
アプリケーションは引き続きエラーから回復できる必要がありますが、アプリケーションが不整合な状態を認識しない限り、トランザクションはサイレントに失敗することはありません。
セマンティクス
リソースマネージャーまたはネットワークがフェーズ1でダウンした場合、トランザクションマネージャーは致命的なエラー(リソースマネージャーに接続できません)を検出し、サブトランザクションを失敗としてマークします。ネットワークが復旧すると、参加しているすべてのリソースマネージャーでトランザクションが中止されます。
フェーズ2でリソースマネージャーまたはネットワークがダウンした場合、トランザクションマネージャーはリソースマネージャーが復旧するまでポーリングを続けます。リソースマネージャーに再接続すると、RMにトランザクションをコミットするように指示します。RMが「不明なTxID」の行に沿ってエラーを返した場合、TMはRMにデータ損失の問題があることを認識します。
フェーズ1でTMがダウンした場合、ネットワーク接続の切断が原因でタイムアウトまたはエラーを受信しない限り、クライアントはTMが復旧するまでブロックします。この場合、クライアントはエラーを認識し、再試行するか、中止自体を開始できます。
TMがフェーズ2でダウンした場合、TMが復旧するまでクライアントをブロックします。トランザクションはすでにコミット可能であると報告されており、TMが復旧するまでブロックされる可能性はありますが、致命的なエラーがクライアントに表示されることはありません。TMは、トランザクションがコミットされていない状態のままであり、RMが復旧したときに、RMをポーリングしてコミットします。
リソースマネージャーでのコミット後のデータ損失イベントは、トランザクションマネージャーによって処理されず、RMの復元力の関数です。
2フェーズコミットはフォールトトレランスを保証しません-フォールトトレランスに対処するプロトコルの例についてはPaxosを参照してください-しかし、分散トランザクションの部分的な障害が気付かれずに進むことができないことを保証します。
- この種の失敗は、以前にコミットされたトランザクションからのデータも失う可能性があることに注意してください。2フェーズコミットは、リソースマネージャーがデータを失ったり破損したりしないこと、またはDR手順が失敗しないことを保証するものではありません。