MQSeries 関数は、さまざまなシナリオで使用できます。このセクションでは、 基本メッセージング、アプリケーション接続、およびデータ・パブリケーションなどの 一般的なシナリオについて検討します。
すべてのデータベース・アプリケーションが同じ DB2 サーバーに接続すると、 MQSeries DB2 関数によって最も基本的な形式のメッセージングが行われます。クライアントは、 データベース・サーバーに対してローカルである場合と、ネットワーク環境に分散している場合が あります。
単純なシナリオでは、クライアント A が MQSEND 関数を呼び出して、ユーザー定義の ストリングをデフォルトのサービス・ロケーションに送ります。次に、データベース・サーバー上 の DB2 内で MQSeries 関数が実行されます。その後、クライアント B が MQRECEIVE 関数を 呼び出して、デフォルト・サービスに定義されているキューの先頭にあるメッセージを除去し、 それをクライアントへ戻します。再び、この作業を行うための MQSeries 関数が DB2 によって 実行されます。
データベース・クライアントでは、多数の方法で単純なメッセージングを使用できます。 一般的なメッセージングの使用法には次のようなものがあります。
次のシナリオでは、上記の単純なシナリオを拡張して、リモート・メッセージングを 組み込みます。つまり、メッセージがマシン A とマシン B 間で送信されます。以下の ようなステップがあります。
DB2 ユーザーまたは開発者は、MQSEND を使用して、送信するデータ、送信先、および 送信日時を選択します。業界では、これを「送信および喪失」と呼びます。これは、 送信側が、メッセージを必ず宛先に届ける MQSeries の保証された送達プロトコルを 信頼して、単純にメッセージを送ることを意味しています。この例を次に示します。
例 4: ポリシー highPriority を使用してユーザー定義のストリングを サービス・ポイント myplace に送るには:
VALUES DB2MQ.MQSEND('myplace','highPriority','test')
ここでは、ポリシー highPriority が、AMI リポジトリーに定義されているポリシーを 参照します。このポリシーは、MQSeries の優先順位を最高レベルに設定し、サービスのその他の 品質 (たとえば、持続性など) を調整するものです。
メッセージの内容は、SQL とユーザー指定データの有効な組み合わせから成ります。 これには、ネストされた関数、演算子、およびキャストが含まれます。たとえば、 表 EMPLOYEE に VARCHAR 列の LASTNAME、FIRSTNAME、および DEPARTMENT があるとします。 DEPARTMENT 5LGA の各従業員の情報が含まれているメッセージを送信するには、次のようにします。
例 5:
SELECT DB2MQ.MQSEND(LASTNAME || ' ' || FIRSTNAME || ' ' || DEPARTMENT) FROM EMPLOYEE WHERE DEPARTMENT = '5LGA'
この表に整数の AGE 列も含まれていた場合は、次のように組み込まれます。
例 6:
SELECT DB2MQ.MQSEND(LASTNAME || ' ' || FIRSTNAME || ' ' || DEPARTMENT|| ' ' || char(AGE)) FROM EMPLOYEE WHERE DEPARTMENT = '5LGA'
最後に、次の例では、有効な SQL 式を使用してメッセージ内容を取得できる方法を 示します。2 番目の表 DEPT に varchar 列の DEPT_NO とDEPT_NAME が含まれていると します。従業員の LASTNAME と DEPT_NAME が含まれているメッセージを送ることが できます。
例 7:
SELECT DB2MQ.MQSEND(e.LASTNAME || ' ' || d.DEPTNAME) FROM EMPLOYEE e, DEPT d WHERE e.DEPARTMENT = d.DEPTNAME
MQSeries DB2 関数を使用すると、メッセージの受信または読み取りが可能です。 読み取りと受信の違いは、読み取りではキューの先頭にあるメッセージをキューから 除去せずに戻す一方、受信操作ではメッセージがキューから除去されます。受信操作を 使用してメッセージを取り出した場合は、1 度しかメッセージを取り出すことが できませんが、読み取り操作を使用してメッセージを取り出した場合は、同じ メッセージを何度も取り出すことができます。この例を次に示します。
例 8:
VALUES DB2MQ.MQREAD()
この例では、デフォルト品質のサービス・ポリシーを使用して、デフォルト・サービスに 定義されているキューの先頭にあるメッセージを含む VARCHAR ストリングを戻します。 読み取るメッセージがない場合は、NULL 値が戻されることに注意してください。キューは この操作では変更されません。
例 9:
VALUES DB2MQ.MQRECEIVE('Employee_Changes')
上記の例では、デフォルト・ポリシーを使用して、Employee_Changes サービスに 定義されているキューのヘッドからメッセージを除去する方法を示しています。
DB2 の非常に強力な機能の 1 つに、ユーザー定義の (またはDB2 提供の) 関数から表を 生成する機能があります。この表関数機能を活用すると、キューの内容を DB2 表として 実体化することができます。次の例は、これを最も単純な形式で示しています。
例 10:
SELECT t.* FROM table ( DB2MQ.MQREADALL()) t
この照会によって、デフォルト・サービスに定義されているキューの中のすべての メッセージと、これらのメッセージに関するメタデータから構成された表が戻されます。 戻される表の構造の完全な定義は「付録」にありますが、最初の列はメッセージの内容を 反映し、残りの列にはメタデータが格納されます。メッセージだけを戻すには、例を 次のように書き換えます。
例 11:
SELECT t.MSG FROM table (DB2MQ.MQREADALL()) t
表関数によって戻される表は、データベースから直接取り出される表と何ら 変わりありません。つまり、この表をさまざまな方法で利用できるということです。 たとえば、表の内容を別の表と結合したり、キューの中のメッセージの数をカウントしたり することができます。
例 12:
SELECT t.MSG, e.LASTNAME FROM table (DB2MQ.MQREADALL() ) t, EMPLOYEE e WHERE t.MSG = e.LASTNAME
例 13:
SELECT COUNT(*) FROM table (DB2MQ.MQREADALL()) t
この場合も、表関数で視点を作成することによって、表のソースがキューであるという 事実を隠すことができます。たとえば、次の例では、NEW_EMPLOYEES という名前の サービスが参照しているキューに、NEW_EMP という名前の視点を作成します。
例 14:
CREATE VIEW NEW_EMP (msg) AS SELECT t.msg FROM table (DB2MQ.MQREADALL()) t
この場合、視点はメッセージ全体を含む 1 つの列だけで定義されています。メッセージの 構造が単純な場合、たとえば固定長のフィールドが 2 つある場合などは、DB2 の組み込み関数を 使用して、メッセージを解析し、2 つの列に分けるのが順当な方法です。たとえば、特定の キューに送られるメッセージに必ず 18 文字のラストネームが含まれており、その後に 18 文字の ファーストネームが続く場合は、各フィールドを含むビューを別々の列に次のように定義できます。
例 15:
CREATE VIEW NEW_EMP2 AS SELECT left(t.msg,18) AS LNAME, right(t.msg,18) AS FNAME FROM table(DB2MQ.MQREADALL()) t
DB2 ストアード・プロシージャー・ビルダーの新機能である MQSeries Assist Wizard を 使用すると、区切られたメッセージ構造を列にマップする、新しい DB2 表関数と視点を 作成できます。
最後に、メッセージの内容をデータベースに保管しておくとよいでしょう。メッセージ 内容を操作および保管するには、SQL のすべての能力を使用すれば行うことができます。 この最も単純な例を次に示します:
例 16:
INSERT INTO MESSAGES SELECT t.msg FROM table (DB2MQ.MQRECEIVEALL()) t
表 MESSAGES に 1 つの列 VARCHAR(2000) があるとします。上記のステートメントに よって、デフォルト・サービス・キューからのメッセージが表に挿入されます。 この技法は、さまざまな状況に応じて変化させることができます。
アプリケーション統合は、多くのソリューションの共通要素です。購入した アプリケーションを既存のインフラストラクチャーに統合するか、または新しく開発された アプリケーションを既存の環境に統合するかにかかわらず、さまざまな種類のサブシステムの コレクションをつなぎ合わせて作業全体を形成するというタスクに直面することがよくあります。 MQSeries は一般に、アプリケーションを統合するための不可欠なツールであるという 評価を受けています。MQSeries は、ほとんどのハードウェア、ソフトウェア、および 言語環境プログラムにアクセス可能で、さまざまな種類のアプリケーションのコレクションに 相互接続する手段を提供します。
このセクションでは、いくつかのアプリケーション統合のシナリオと、DB2 でのその 使用法について説明します。トピックが非常に広範囲なので、アプリケーション統合を 包括的に扱うのは、この作業の目的とするところではありません。したがってここでは、 2 つの単純なトピック、つまり要求/応答通信、および MQSeries Integrator と 発行/サブスクリプションだけを取り上げます。
要求/応答 (R/R) 通信方式は、あるアプリケーションが別のアプリケーションの サービスを要求するという、非常に一般的な技法です。これを行うために、要求側が サービス提供側に、何らかの作業の実行を求めるメッセージを送る方法があります。作業が 完了したら、提供側は、結果 (または単に完了の確認) を要求側へ戻すかどうかを 決めることができます。しかし、上記の基本的なメッセージング技法を使用した場合、 送信側の要求をサービス提供側の応答に接続するものが何もありません。要求側が 続行する前に応答を待機しない限りは、各応答をその要求に関連付けるためにいくつかの メカニズムを使用する必要があります。開発者にこのようなメカニズムの作成を強いる ことなく、MQSeries は、メッセージの交換時にメッセージを相関させることを可能に する相関 ID を提供します。
このメカニズムはさまざまな方法で使用できますが、最も単純な方法は、要求側が既知の 相関 ID を使用してメッセージにマークを付ける方法です。この例を次に示します。
例 17:
DB2MQ.MQSEND ('myRequester','myPolicy','SendStatus:cust1','Req1')
このステートメントでは、最後のパラメーター Req1 を MQSEND ステートメントに 上方から追加して、要求の相関 ID を指示しています。
この特定の要求に対する応答を受け取るには、次のように、対応する MQRECREIVE ステートメントを 使用して、指示されたサービスに定義されている最初のメッセージを選択的に取り出してください。
例 18:
DB2MQ.MQRECEIVE('myReceiver','myPolicy','Req1')
要求をサービスするアプリケーション・サービスがビジー状態であるときに、応答が 送られる前に要求側が上記の MQRECEIVE を発行すると、この相関 ID に一致する メッセージは見つかりません。
サービス要求と相関 ID の両方を受け取るには、次のようなステートメントを使用します。
例 19:
SELECT msg, correlid FROM table (DB2MQ.MQRECEIVEALL('aServiceProvider','myPolicy',1)) t
これにより、最初の要求のメッセージと相関 ID がサービス aServiceProvider から 戻されます。
サービスが実行されたら、aRequester に記述されているキューへ応答メッセージを 送ります。一方、サービス要求側は他の作業を行うことが可能です。実際、初期サービス 要求へ、設定された時間内に応答する保証はありません。このようなアプリケーション・ レベルのタイムアウトは、開発者が管理する必要があります。また、要求側は、応答の存在を 検出するためにポーリングする必要があります。
このような時間に依存しない非同期処理の利点は、要求側とサービス提供者が相互に 完全に独立して実行する点です。この方法は、アプリケーションが断続的に接続される環境と、 複数の要求または応答が処理前に集約されるバッチ指向性の高い環境の両方に適合します。 この種の集約は多くの場合、データウェアハウスまたは操作可能なデータ保管を定期的に 更新するために、データウェアハウス環境で使用されます。
アプリケーション統合のもう 1 つの一般的なシナリオは、1 つのアプリケーションが 別のアプリケーションへインタレストのイベントについて通知するというものです。これは、 別のアプリケーションがモニターしているキューへメッセージを送るという簡単な方法で 行うことができます。メッセージの内容は、ユーザー定義ストリングにすることも、 データベース列から構成することもできます。多くの場合、単純なメッセージとは、 MQSEND 関数を使用して送る必要があるものすべてを指します。このようなメッセージを 複数の受信側に同時に送る必要があるときには、MQSeries AMI の配布先リスト機能を 使用できます。
配布先リストは、AMI 管理ツールを使用して定義します。配布先リストは、個々の サービスのリストで構成されます。配布先リストに送られるメッセージは、リストに 定義されているあらゆるサービスに転送されます。これは特に、いくつかのサービスが 常にすべてのメッセージに関与することが分かっているときに役立ちます。次の例では、 配布先リスト interestedParties にメッセージを送信します。
例 20:
DB2MQ.MQSEND('interestedParties','information of general interest');
特定のサービスが受け取るメッセージに対してより多くの制御が必要な場合は、 発行/サブスクリプション機能が必要です。発行/サブスクリプション・システムは一般に、 多くのサブスクライバーが複数のパブリッシャーからのメッセージを受け取るために 登録できる、スケーラブルで安全な環境を提供します。この機能をサポートするために、 MQSeries Integrator または MQSeries 発行/サブスクリプション機能とともに、 MQPublish インターフェースを使用できます。
MQPublish を使用すると、ユーザーは、メッセージに関連付けるトピックをオプションで 指定できます。トピックによって、サブスクライバーは、受け入れるメッセージをより 明確に指定できます。手順は以下の通りです。
すべてのデフォルトとヌル・トピックを使用してこのデータを発行するには、 次のステートメントを使用します。
例 21:
SELECT DB2MQ.MQPUBLISH(LASTNAME || ' ' || FIRSTNAME || ' ' || DEPARTMENT|| ' ' ||char(AGE)) FROM EMPLOYEE WHERE DEPARTMENT = '5LGA'
すべてのパラメーターを完全に指定し、LASTNAME だけを含むようにメッセージを 単純化すると、ステートメントは次のようになります。
例 22:
SELECT DB2MQ.MQPUBLISH('HR_INFO_PUB', 'SPECIAL_POLICY', LASTNAME, 'ALL_EMP:5LGA', 'MANAGER') FROM EMPLOYEE WHERE DEPARTMENT = '5LGA'
このステートメントは、SPECIAL_POLICY サービスを使用して、 HR_INFO_PUB パブリケーション・サービスへメッセージを発行します。メッセージは、 送信側が MANAGER トピックであることを示しています。トピック・ストリングから、 「:」で連結することによって複数のトピックを指定できることがわかります。この例では、 2 つのトピックが使用されているため、サブスクライバーは、ALL_EMP または 5LGA の どちらかについて登録し、これらのメッセージを受け取ることができます。
発行されたメッセージを受け取るには、まず指定されたトピックが含まれている 関係するメッセージを登録し、メッセージを送るサブスクライバー・サービスの名前を 指示する必要があります。AMI サブスクライバー・サービスは、ブローカー・サービスと 受信側サービスを定義することに注意してください。ブローカー・サービスとは、 サブスクライバーが発行/サブスクリプション・ブローカーと通信する方法のことで、 受信側サービスとは、サブスクリプション要求と一致するメッセージの宛先のことです。 次のステートメントでは、トピック ALL_EMP 内のインタレストを登録します。
例 23:
DB2MQ.MQSUBSCRIBE('aSubscriber', 'ALL_EMP')
アプリケーションがサブスクライブすると、トピック ALL_EMP とともに発行される メッセージは、サブスクライバー・サービスによって定義されている受信側サービスに 転送されます。アプリケーションには、並列サブスクリプションが複数存在することが あります。サブスクリプションに適合するメッセージを取得するには、通常のメッセージ 検索機能を使用できます。たとえば、サブスクライバー・サービス aSubscriber に、 受信側サービスが aSubscriberReceiver であると定義されている場合は、次の ステートメントで最初のメッセージが非破壊的に読み取られます。
例 24:
DB2MQ.MQREAD('aSubscriberReceiver')
メッセージと、メッセージが発行されたトピックの両方を判別するには、表関数を 使用します。次のステートメントでは、最初の 5 つのメッセージを aSubscriberReceiver から 受け取り、メッセージとトピックの両方を表示します。
例 25:
SELECT t.msg, t.topic FROM table (DB2MQ.MQRECEIVEALL('aSubscriberReceiver',5)) t
トピック ALL_EMP のメッセージをすべて読み取るには、発行する SQL の能力を 次のように調整します。
例 26:
SELECT t.msg FROM table (DB2MQ.MQREADALL('aSubscriberReceiver')) t WHERE t.topic = 'ALL_EMP'
それ以上特定のトピックにサブスクリプションしない場合は、次のようなステートメントを 使用して、明示的にアンサブスクリプションする必要があります。
例 27:
DB2MQ.MQUNSUBSCRIBE('aSubscriber', 'ALL_EMP')
このステートメントが実行されると、発行/サブスクリプション・ブローカーは それ以上、このサブスクリプションに一致するメッセージを送信しません。
データベース・メッセージングでのもう 1 つの重要な技法は、自動発行です。 DB2 内でトリガー機能を使用すると、トリガー呼び出しの一部として自動的にメッセージを 発行できます。データ発行を自動化する技法はほかにもありますが、このトリガー・ベースの 方法では、管理者または開発者に、メッセージ内容の構成における自由度と、 トリガー・アクションの定義における柔軟性が与えられます。トリガーの使用と同様に、 実行の頻度とコストにも注意を払う必要があります。下の例では、トリガーを MQSeries DB2 関数とともに使用する方法を示します。
次の例では、新しい従業員が雇用されるたびにメッセージを発行する簡単な方法を 示します。NEW_EMP の登録済みインタレストとともに HR_INFO_PUB サービスに サブスクリプションするユーザーまたはアプリケーションはいずれも、新しい従業員の 日付、名前、および部署が含まれたメッセージを受け取ります。
例 28:
CREATE TRIGGER new_employee AFTER INSERT ON employee REFERENCING NEW AS n FOR EACH ROW MODE DB2SQL VALUES DB2MQ.MQPUBLISH('HR_INFO_PUB&', 'NEW_EMP', current date || ' ' || LASTNAME || ' ' || DEPARTMENT)