バインドされたセッションの使用

バインドされたセッションを使用すると、同一サーバー上の複数のセッションにまたがるアクションの調整が容易になります。バインドされたセッションでは、2 つ以上のセッションで同じトランザクションとロックを共有できます。また、ロックの競合が発生しないで同じデータを操作できます。バインドされたセッションは、同じアプリケーション内の複数のセッションからも、セッションが異なる複数のアプリケーションからも作成できます。

バインドされたセッションに参加するには、セッションから sp_getbindtoken または srv_getbindtoken (オープン データ サービス経由) を呼び出して、バインド トークンを取得します。バインド トークンは、バインドされたトランザクションをそれぞれ一意に識別する文字列です。取得したバインド トークンは、現在のセッションにバインドされる他のセッションに送信されます。他のセッションは、最初のセッションから受信したバインド トークンを使用して sp_bindsession を呼び出すことにより、トランザクションにバインドされます。

注意

sp_getbindtoken または srv_getbindtoken が成功するには、セッションにアクティブなユーザー トランザクションが含まれている必要があります。

最初のセッションを作成するアプリケーション コードから、その後最初のセッションに他のセッションをバインドするアプリケーション コードに、バインド トークンが転送される必要があります。別のプロセスによって開始されたトランザクションのバインド トークンをアプリケーションで取得するための Transact-SQL ステートメントや API 関数はありません。バインド トークンは、次に示す方法を使用して転送できます。

  • バインドされるセッションがすべて同じアプリケーション プロセスから開始されている場合、バインド トークンをグローバル メモリに格納するか、パラメータとして関数に渡すことができます。

  • バインドされるセッションが異なるアプリケーション プロセスで作成されている場合、RPC (リモート プロシージャ コール) や DDE (動的データ交換) などの IPC (プロセス間通信) を使用してバインド トークンを転送できます。

  • SQL Server データベース エンジンのインスタンス内の、最初のセッションにバインドを試みるプロセスから読み取れるテーブルに、バインド トークンを格納します。

バインドされたセッションのうち、一度にアクティブにできるのは 1 つだけです。あるセッションがインスタンス上でステートメントを実行している場合、またはインスタンスからの結果が保留中の場合、そのセッションにバインドされている他のセッションでは、現在のセッションが処理を完了するか、現在のステートメントがキャンセルされるまで、そのインスタンスにアクセスできません。そのインスタンスでバインドされた別のセッションからのステートメントが処理されていてビジー状態の場合、トランザクション領域が使用中なのでそのセッションを後で再試行する必要があることを示すエラーが発生します。

セッションをバインドするときに、各セッションの分離レベル設定が保持されます。SET TRANSACTION ISOLATION LEVEL を使用して 1 つのセッションの分離レベル設定を変更しても、そのセッションにバインドされている他のセッションの分離レベル設定は変更されません。

バインドされたセッションの種類

バインドされたセッションには "ローカル" と "分散" の 2 種類があります。

  • バインドされたローカル セッション

    バインドされたセッションは、データベース エンジンの 1 つのインスタンスで、1 つのトランザクションのトランザクション領域を共有できます。

  • バインドされた分散セッション

    Microsoft 分散トランザクション コーディネータ (MS DTC) を使用して、バインドされたセッションは、トランザクション全体がコミットまたはロールバックされるまで、2 つ以上のインスタンス間で同じトランザクションを共有できます。

バインドされた分散セッションは、文字列のバインド トークンによって識別されるのではなく、分散トランザクション ID 番号によって識別されます。バインドされたセッションがローカル トランザクションに関係していて、リモート サーバーで SET REMOTE_PROC_TRANSACTIONS ON を指定して RPC を実行している場合、MS DTC により、バインドされたローカル トランザクションがバインドされた分散トランザクションに自動的に昇格し、MS DTC セッションが開始します。

バインドされたセッションの用途

以前のバージョンの SQL Server では、バインドされたセッションは、主に、特定の拡張ストアド プロシージャの開発に使用されていました。このような拡張ストアド プロシージャでは、セッションを呼び出すプロセスに代わって Transact-SQL ステートメントを実行する必要があります。呼び出しプロセスをバインド トークンで拡張ストアド プロシージャのパラメータの 1 つとして渡せば、プロシージャは呼び出し側プロセスのトランザクション領域を結合できます。これにより、拡張ストアド プロシージャを呼び出し元プロセスに統合できます。

SQL Server データベース エンジンでは、CLR を使用して記述されたストアド プロシージャは、拡張ストアド プロシージャよりも安全性、拡張性、安定性が高くなります。CLR ストアド プロシージャでは、sp_bindsession ではなく SqlContext オブジェクトを使用して呼び出し元セッションのコンテキストを結合します。

また、バインドされたセッションは、1 つのビジネス トランザクションで個別のプログラムが連携するようなビジネス ロジックを持つ、3 層構造のアプリケーションの開発に使用できます。このようなプログラムでは、データベースへのアクセス調整に注意を払う必要があります。2 つのセッションで同じロックを共有するので、その 2 つのプログラムで同じデータを同時に変更しないでください。トランザクションの一部として機能するセッションはどの時点においても 1 つだけです。並列実行はできません。すべての DML ステートメントが完了しそれらの結果が取得された時点など、セッション間のトランザクション切り替えは明確な降伏点でのみ行えます。