仮想クロック値の使用

KTM は、各トランザクション マネージャー オブジェクトの仮想クロックを提供します。 リソース マネージャーが ZwCreateTransactionManagerを呼び出すと、KTM はオブジェクトの仮想クロック値を 1 に設定します。 KTM は、コミット操作が開始されるたびに仮想クロック値をインクリメントします。 KTM は、ログ ストリームに書き込むたびに、ログ レコードに現在の仮想クロック値を含めます。

リソース マネージャーが ZwRecoverTransactionManagerを呼び出すと、KTM はストリームの末尾までログ ストリーム レコードを読み取り、トランザクション マネージャー オブジェクトの仮想クロック値を、オブジェクトのログ ストリームで最後に見つけた値に設定します。

リソース マネージャーが ZwRollforwardTransactionManagerを呼び出すと、KTM は指定したクロック値までのログ ストリーム レコードを読み取り、トランザクション マネージャー オブジェクトの仮想クロック値を指定したクロック値に設定します。

KTM を使用すると、リソース マネージャーと上位トランザクション マネージャーは、トランザクション マネージャー オブジェクトの仮想クロック値を変更できますが、通常、クロック値を変更する必要はありません。

仮想クロック値を変更するタイミング

通常、トランザクション処理システム (TPS) は、TPS のコンポーネントが複数のログ ストリームを同期しようとしている場合を除き、仮想クロック値を変更する必要はありません。

たとえば、複数のリソース マネージャーが TPS に含まれていて、事前準備/準備/コミット シーケンス中に相互に通信するとします。 また、各リソース マネージャーが、一意のログ ストリームを持つトランザクション マネージャー オブジェクトを作成するとします。 KTM が復旧操作中に、すべてのリソース マネージャーの状態を同じ時点に復元することを確認するために、これらのリソース マネージャーは、次の手順を使用する可能性があります。

  • あるリソース マネージャーが別のリソース マネージャーと通信すると、KTM または別のリソース マネージャーから受信した最新の仮想クロック値を渡します。

  • リソース マネージャーは、仮想クロック値を受け取る KTM ルーチンを呼び出すたびに (このトピックの次のセクションを参照)、KTM または別のリソース マネージャーから受信した最も高いクロック値を渡します。

  • 各リソース マネージャーは、仮想クロック値をログ ストリームに書き込み、ロールバックまたは復旧操作を実行するときにこれらの値を使用します。

これらの手順により、KTM が各トランザクションマネージャオブジェクトに格納する仮想クロック値は、ほぼ一致するか、完全に一致するようになります。 そのため、復旧操作によって KTM がログ ストリームを読み取る場合、またはロールバック操作によってリソース マネージャーがログ ストリームを読み取る場合、復旧またはロールバックは同期されたログ ストリームに基づいて行われます。

仮想クロック値を変更する方法

リソース マネージャーは、 ZwPrePrepareCompleteZwPrepareCompleteZwCommitCompleteZwRollbackCompleteZwReadOnlyEnlistment または ZwSinglePhaseRejectに新しい値を渡すことによって、仮想クロック値を変更できます。

上位のトランザクション マネージャー は、 ZwPrePrepareEnlistmentZwPrepareEnlistmentZwCommitEnlistment, または ZwReadOnlyEnlistmentに新しい値を渡すことによって、仮想クロック値を変更できます。

さらに、リソース マネージャーまたは上位のトランザクション マネージャーは ResourceManagerNotification コールバック ルーチンを使用する場合、コールバック ルーチンが受け取る仮想クロック値を変更できます。 その後、KTM は更新された値を保存します。

リソース マネージャーまたは上位のトランザクション マネージャーが 新しいクロック値を KTM に渡す場合、KTM は、現在のクロック値より大きい場合にのみ、新しい値を保存します。 それ以外の場合、KTM は現在のクロック値を保持します。

リソース マネージャーと上位トランザクション マネージャーは、 ZwQueryInformationTransactionManager ルーチンを呼び出すことによって、トランザクション マネージャー オブジェクトの仮想クロック値を取得できます。