メッセージ交換グループ

メッセージ交換グループは、関連するメッセージ交換のグループを識別します。メッセージ交換グループでは、特定のビジネス タスクに伴うメッセージ交換を、アプリケーションで容易に調整することができます。

すべてのメッセージ交換は、1 つのメッセージ交換グループに属しています。すべてのメッセージ交換グループは特定のサービスに関連付けられており、グループ内のすべてのメッセージ交換は、そのサービスとメッセージ交換を行います。メッセージ交換グループには、任意の数のメッセージ交換を含めることができます。

SQL Server は、メッセージ交換グループを使用して、特定のビジネス タスクに関連するメッセージへの、EOIO (exactly-once-in-order) アクセスを提供します。アプリケーションがメッセージを送信または受信すると、SQL Server は、そのメッセージが属するメッセージ交換グループをロックします。これにより、一度に 1 つのセッションだけが、そのメッセージ交換グループのメッセージを受信できます。メッセージ交換グループをロックすることで、アプリケーションが、各メッセージ交換のメッセージを EOIO (exactly once in order) 処理できることが保証されます。メッセージ交換グループには複数のメッセージ交換を含めることができるため、アプリケーションはメッセージ交換グループを使用して、同じビジネス タスクに関連するメッセージを識別し、それらのメッセージをまとめて処理することができます。

メッセージ交換グループは、メッセージ交換の参加者の間で共有されません。そのため、メッセージ交換の各参加者は、そのメッセージ交換を目的に応じてグループ化することができます。アプリケーションは、サービスによる特別なサポートを必要とせずに、サービス間の複雑な相互作用を管理できます。

メッセージ交換グループの例

人事アプリケーションが、給与支払いサービスからの情報と、手当てサービスからの情報を結合する GetEmployeeInformation サービスを備えているとします。GetEmployeeInformation サービスは、各サービスとのメッセージ交換を開始し、1 つのメッセージ交換を、同じメッセージ交換グループ内の別のメッセージ交換に関連付けます。Service Broker は、これら 2 つのメッセージ交換での各着信メッセージに対して、そのメッセージが給与支払いサービスと手当てサービスのどちらから着信したかに関係なく、メッセージ交換グループ ID を追加します。これらのメッセージ交換は同じメッセージ交換グループに属しているため、Service Broker は、GetEmployeeInformation サービスで実行中の要求の数に関係なく、GetEmployeeInformation サービスが手当て情報を給与支払い情報と照合するために必要なすべての情報を提供します。

給与支払いサービスへのメッセージと、手当てサービスへのメッセージには、GetEmployeeInformation によって作成されたメッセージ交換グループのメッセージ交換グループ情報は含まれません。各サービスは独立して実行され、GetEmployeeInformation サービスだけが、ビジネス タスク全体に関する情報を保持しています。各サービスを相互に独立させることで、各サービスのコードが単純になり、メンテナンスも容易になります。この独立性を維持することのもう 1 つの利点は、1 つのサービスが利用不可能でも、他のサービスは操作を続行できることです。

アプリケーション状態の編成

メッセージ交換グループの利点の 1 つは、メッセージ交換グループ ID が、アプリケーション状態を識別および取得するために便利なキーであることです。メッセージ交換グループ ID を使用することにより、データベースでアプリケーション状態を保持することが容易になります。タスクを完了するために多数のメッセージを交換する必要がある場合には、アプリケーション状態を保持するためだけにアプリケーションのインスタンスを実行し続けることは、効率的ではありません。メッセージ間で、タスクに関連付けられたデータをデータベースに格納し、そのタスクに関連付けられた次のメッセージを受信したときに取得するようにすれば、アプリケーションのスケーラビリティが向上します。メッセージ交換グループ ID は、アプリケーション開発者が提供する状態テーブルの主キーとして使用することで、特定のタスクに関連付けられた状態を高速に取得できます。メッセージ交換グループ ID を使用して状態を保持する方法の詳細については、「状態管理」を参照してください。

SQL Server は、アプリケーションがメッセージを送受信するたびにメッセージ交換グループをロックするため、アプリケーションは、他のプログラムが同じ状態データを同時に更新することを明示的に防止する必要がありません。アプリケーションは、単にメッセージ交換グループをロックし、状態を復元し、メッセージを処理し、状態を更新して、トランザクションをコミットします。

便宜上、SQL Server は、アプリケーションがメッセージを受信しなくても次の使用可能なメッセージ交換グループをロックすることを許可します。GET CONVERSATION GROUP ステートメントを使用することで、アプリケーションはメッセージを処理する前に、メッセージ交換グループをロックし、状態を復元することができます。詳細については、GET CONVERSATION GROUP (Transact-SQL) ステートメントを参照してください。

メッセージ交換グループの有効期間

Service Broker は、メッセージ交換グループの有効期間を管理します。メッセージ交換グループを明示的に作成したり、破棄したりする必要はありません。Service Broker は、次の状況において、新しいメッセージ交換グループを作成します。

  • アプリケーションが、既存のメッセージ交換グループに関係しない新しいメッセージ交換を開始する場合。Service Broker は、新しいメッセージ交換グループを作成し、そのメッセージ交換グループに新しい ID を割り当てます。

  • アプリケーションが、現在は存在しないメッセージ交換グループ ID に関係するメッセージ交換を開始する場合。この場合、Service Broker は指定された ID で新しいメッセージ交換グループを作成します。したがって、メッセージ交換グループ ID に任意の値を割り当てることができます。

  • Service Broker が、他のサービスによって開始された新しいメッセージ交換での最初のメッセージを受信した場合。この場合、Service Broker は、サービス名と、ブローカ インスタンス ID (存在する場合) を使用して、次のことを実行します。

    1. 適切なキューを検索します。

    2. 新しいメッセージ交換グループを作成し、キューに関連付けます。

    3. 新しいメッセージ交換ハンドルを作成し、新しいメッセージ交換グループに追加します。

    4. 着信メッセージをキューに入れます。

Service Broker は、メッセージ交換グループ ID を、そのメッセージ交換グループを作成したメッセージ交換のメタデータに追加します。Service Broker は、メッセージ交換グループに関連付けられたメッセージ交換のメッセージを受信すると常に、そのメッセージをキューに入れる前に、メッセージ交換グループ ID をそのメッセージに追加します。

メッセージ交換グループ ID は、それが Service Broker によって作成された時点から、その ID に関連付けられたすべてのメッセージ交換が終了するまで有効です。つまり、メッセージ交換グループ ID は、グループ内のいずれかのメッセージ交換がアクティブである間は有効であることが保証されます。

アプリケーション状態の管理にメッセージ交換グループ ID を使用するアプリケーションは、開発者が提供する状態テーブルを使用します。アプリケーションは、状態が不要になったと判断した時点で、その状態を状態テーブルから削除する必要があります。多くの場合、アプリケーションは、タスクが正常に完了するか、またはタスクが完了できないことを示すエラーが発生した後で、状態を削除します。これらの場合には通常、アプリケーションは、最後の応答メッセージを送信し、メッセージ交換を終了するトランザクション内で状態を削除するためのコマンドを含んでいます。この方法では、アプリケーション状態の有効期間とメッセージ交換グループ ID の有効期間は同じになります。送信操作が失敗すると、削除操作はロールバックされます。同様に、削除操作が失敗すると、送信操作はロールバックされ、SQL Server はメッセージを送信しません。どちらの場合でも、アプリケーション状態とメッセージ交換グループ ID は有効のままになります。両方の操作が成功した場合には、プログラムによって関連付けられているアプリケーション状態が削除されると同時に、メッセージ交換グループ ID の有効期間が終了します。