リソース マネージャの実装
トランザクションで使用される各リソースはリソース マネージャによって管理され、その動作はトランザクション マネージャによって調整されます。リソース マネージャは、トランザクション マネージャと連携してアプリケーションに原子性と分離を保証します。Microsoft SQL Server、永続的なメッセージ キュー、メモリ内ハッシュ テーブルはすべて、リソース マネージャの例です。
リソース マネージャは、永続性データまたは揮発性データを管理します。リソース マネージャの永続性または揮発性とは、リソース マネージャがエラーの回復をサポートするかどうかを意味します。リソース マネージャがエラーの回復をサポートする場合、フェーズ 1 (準備) 中にデータが永続ストレージに保存されます。したがって、リソース マネージャがダウンした場合でも、回復時にトランザクションへの再参加を行い、トランザクション マネージャから受信した通知に基づいて適切な動作を実行できます。一般に、揮発性リソース マネージャは、メモリ内のデータ構造 (たとえば、メモリ内のトランザクション ハッシュ テーブル) などの揮発性リソースを管理し、永続的リソース マネージャは、より永続的なバッキング ストアを持つリソース (たとえば、バッキング ストアがディスクであるデータベース) を管理します。
リソースをトランザクションに参加させるには、リソースをトランザクションに登録する必要があります。Transaction クラスは、この機能を提供する一連のメソッドを定義しています。これらのメソッドの名前は Enlist で始まります。さまざまな Enlist メソッドは、リソース マネージャが持つ各種の参加リストにそれぞれ対応しています。具体的には、揮発性リソースには EnlistVolatile メソッド、永続性リソースには EnlistDurable メソッドを使用します。簡単に説明すると、リソースが永続性をサポートするかどうかに応じて、EnlistDurable メソッドまたは EnlistVolatile メソッドのどちらを使用するかを決定した後、リソース マネージャに IEnlistmentNotification インターフェイスを実装して、2 フェーズ コミット (2PC) に参加するようにリソースを登録する必要があります。2PC の詳細については、「単一フェースおよび複数フェーズでのトランザクションのコミット」を参照してください。
参加により、リソース マネージャは、トランザクションがコミットまたは中止したときに、トランザクション マネージャからのコールバックを取得することを保証します。各参加リストについて、IEnlistmentNotification のインスタンスが 1 つ存在します。通常、トランザクションごとに 1 つの参加リストが存在しますが、リソース マネージャは、同じトランザクションへの複数回の参加を選択できます。
参加後、リソース マネージャはトランザクションの要求に応答します。永続的リソース マネージャは、管理するリソースに対するトランザクションの処理を元に戻したり、やり直したりするための十分な情報を格納しています。このためには、さまざまな方法があります。データのバージョン保持と変更ログの保持という 2 つの手法が一般的に使用されます。
アプリケーションがトランザクションをコミットすると、トランザクション マネージャが 2 フェーズ コミット プロトコルを開始します。トランザクション マネージャはまず、参加している各リソース マネージャに、トランザクションをコミットする準備が整っているかどうかを確認します。リソース マネージャは、コミットの準備、つまりトランザクションをコミットまたは中止できる状態を整える必要があります。
準備フェーズ中に、永続的リソース マネージャは安定したストレージに新旧のデータを記録します。したがって、システム障害が発生してもリソース マネージャはデータを回復できます。リソース マネージャは準備が整うと、トランザクションをコミットまたは中止するかどうかの決定をトランザクション マネージャに通知します。いずれかのリソース マネージャが準備の失敗を報告すると、トランザクション マネージャは各リソース マネージャにロールバック コマンドを送信し、アプリケーションにコミットの失敗を通知します。
準備が整うと、フェーズ 2 でトランザクション マネージャからコミットまたは中止のコールバックを取得するまで、リソース マネージャは待機する必要があります。通常、準備およびコミット プロトコル全体は 1 秒かからずに完了します。システムまたは通信に障害が発生した場合、コミットまたは中止の通知が数分または数時間経っても到着しないことがあります。この間、リソース マネージャはトランザクションの結果について判断できず、トランザクションがコミットまたは中止されたかどうかを認識できません。トランザクションについて判断できない間、リソース マネージャはトランザクションをロックし続けてデータの変更を維持し、これらの変更部分を他のトランザクションから分離した状態にします。
リソース マネージャが失敗すると、そのすべての参加トランザクションは、失敗前に準備またはコミットされたものを除いて中止されます。永続的リソース マネージャは再起動時に、準備フェーズで書き込まれた準備情報を取得することにより、管理するリソースのコミット状態を再構築し、それに応じてトランザクションをコミットまたは中止します。
要約すると、2 フェーズ コミット プロトコルとリソース マネージャの組み合わせにより、トランザクションの原子性と永続性が実現されます。
Transaction クラスは、PSPE (Promotable Single Phase Enlistment) を参加させるための EnlistPromotableSinglePhase メソッドも提供しています。これにより、永続的リソース マネージャ (RM) は、MSDTC による管理のために後で必要に応じてエスカレートできるトランザクションをホストおよび "所有" できます。詳細については、「単一フェーズ コミットおよび昇格可能単一フェーズ通知を使用した最適化」を参照してください。
このセクションの内容
リソース マネージャが通常実行する手順の概要については、次のトピックを参照してください。
永続性リソースまたは揮発性リソースがトランザクションに参加する方法について説明しています。
単一フェースおよび複数フェーズでのトランザクションのコミット
リソース マネージャがコミット通知に応答し、コミットの準備を行うしくみについて説明しています。
永続的リソース マネージャが、どのようにエラーから回復するかについて説明しています。
System.Transactions の 3 つの信頼レベルで、System.Transactions が公開するリソースの種類に対するアクセスがどのように制限されるかについて説明しています。
単一フェーズ コミットおよび昇格可能単一フェーズ通知を使用した最適化
リソース マネージャの実装に使用できる最適化の技法について説明します。
Copyright © 2007 by Microsoft Corporation.All rights reserved.