Comments
Transcript
3章 MQIの追加・拡張 目次 2008/07 日本アイ・ビー・エム システムズ・エンジニアリング㈱
<WebSphere MQ V7 Update Workshop> WebSphere MQ 3章 MQIの追加・拡張 2008/07 日本アイ・ビー・エム システムズ・エンジニアリング㈱ <WebSphere MQ V7 Update Workshop> 目次 メッセージ・プロパティ、メッセージ・セレクター 非同期メッセージ受信(コールバック機能) マークを用いたメッセージブラウズ機能 この資料に含まれる情報は可能な限り正確を期しておりますが、日本アイ・ビー・エム システムズ・エンジニアリング株式会社の正式なレビューを受け ておらず、当資料に記載された内容に関して当ワークショップの主催者である日本アイ・ビー・エム システムズ・エンジニアリング株式会社は何ら保証 するものではありません。 従って、この情報の利用またはこれらの技法の実施はひとえに使用者の責任において為されるものであり、資料の内容によって受けたいかなる被害 に関しても一切の保証をするものではありません。 当資料に記載された製品名または会社名はそれぞれの各社の商標または登録商標です。 2 <WebSphere MQ V7 Update Workshop> 新しいMQI 本章でカバーする範囲 Pub/Sub関連 MQSUB MQSUBRQ サブスクリプション登録 サブスクリプションをリクエスト メッセージ・プロパティ関連 MQSETMP メッセージ・プロパティを設定 MQINQMP メッセージ・プロパティを参照 MQDLTMP メッセージ・プロパティを削除 MQCRTMH メッセージ・ハンドルを作成 MQDLTMH メッセージ・ハンドルを削除 MQBUFMH バッファをメッセージ・ハンドルに変換 MQMHBUF メッセージ・ハンドルをバッファに変換 非同期メッセージ受信 MQCB コールバック関数の登録 MQCTL コールバック関数の制御 (開始/停止) MQCB_FUNCTION コールバック関数の登録(CICS用) 非同期メッセージ送信 MQSTAT 非同期メッセージ受信状況の確認 従来のMQI MQCONN MQCONNX MQDISC MQOEPN MQCLOSE MQPUT MQGET MQPUT1 MQSET MQINQ MQCOMIT MQBACK MQBEGIN キューマネージャーに接続 キューマネージャーに接続(拡張) キューマネージャーから接続 キューをオープン キューをクローズ メッセージを書き込む メッセージを読み込む キューをオープンしてメッセージを 1つ書き込む 属性を設定 属性を参照 メッセージをコミット メッセージをバックアウト グローバルトランザクションを開始 3 <WebSphere MQ V7 Update Workshop> ブランク・ページ 4 <WebSphere MQ V7 Update Workshop> メッセージ・プロパティ 5 <WebSphere MQ V7 Update Workshop> MQIでのメッセージ・プロパティのサポート メッセージ・プロパティとは メッセージに付加的に追加された情報 ユーザー固有のキーワード アプリケーション固有のデータ MQMD ユーザーデータ プロパティ メッセージ・プロパティを利用し、メッセージ・セレクターによる選択受信が可能 メッセージ・プロパティをMQIで設定/参照することができる JMSプロパティも同様にMQIで参照/設定できる MQIアプリケーションは、JMSアプリケーションとの連携時にMQRHF2ヘッダーを意識しなくてもよい JMSアプリケーション V6 MQIアプリケーション send MQGET JMSメッセージ ヘッダー V7 マッピング プロパティ ボディー MQメッセージ MQMD MQRFH2 ユーザーデータ MQIアプリケーション JMSアプリケーション MQGET send マッピング MQRHF2ヘッダーを設定、参照 するプログラムを自前で作成す ることが必要 MQMD プロパティ 6 ユーザーデータ MQRHF2ヘッダーを プロパティとして扱える <WebSphere MQ V7 Update Workshop> メッセージ・プロパティ メッセージ・プロパティの形式はプロパティ名、値のペア 例) MQMD ユーザーデータ Product=‘MQ’、Version=‘v7’ ※MQMDのバージョンはv6と変わっていない StructId、Version以外のMQMDのフィールドをメッセージ・プロパティとして 扱うことが可能 Root.MQMD.<Field>の形式でプロパティ名を指定 例) Root.MQMD.MsgType 注意点 セグメント化されたメッセージはメッセージ・プロパティを持つことはできない 7 <WebSphere MQ V7 Update Workshop> メッセージ・プロパティの設定/参照 MQIアプリケーションはメッセージ・ハンドルを通してメッセージ・プロパティを設定/参照する メッセージ・ハンドルはキューに対するオブジェクト・ハンドルに相当 メッセージ・ハンドルはMQPMO、MQGMOを通してMQPUT、MQGETに渡される メッセージ・プロパティ関連の新規追加されたMQI MQI MQCRTMH MQDLTMH MQSETMP MQINQMP MQDLTMP MQMHBUF MQBUFMH 説明 ・メッセージ・ハンドルを作成する関数 ・メッセージハンドルを除去 ・メッセージ・プロパティをメッセージハンドルに設定 ・メッセージ・プロパティをメッセージハンドルから参照 ・メッセージ・プロパティの除去 ・メッセージハンドルの内容を文字列バッファに書き出す ・文字列バッファの内容をメッセージハンドルに書き込む 8 <WebSphere MQ V7 Update Workshop> メッセージ・プロパティを設定するアプリケーションの流れ メッセージ・プロパティの設定 MQCRTMHでメッセージ・ハンドルの作成 MQSETMPでメッセージ・ハンドルに対してプロパティを設定 MQPUTにメッセージハンドルをセットしMQPUT アプリケーション キュー・マネージャー MQCRTMH MQCRTMH メッセージ・ プロパティの設定 MQSETMP MQPUT メッセージ・ ハンドルの作成 メッセージ・ ハンドル MQPMO メッセージ・ ハンドル メッセージ・ ハンドル MQSETMP メッセージ・ プロパティの設定 プロパティ付の メッセージをPUT 9 <WebSphere MQ V7 Update Workshop> メッセージ・プロパティの設定 コーディング・イメージ メッセージ・プロパティの設定 プロパティ付のメッセージ MQCMHO の設定 MQHMSG Hmsg; MQCRTMH(Hcon, MQCMHO, &Hmsg, &CC, &RC); Loop MQCHARV vsの設定 MQPD pdの設定 MQSETMP(Hcon, Hmsg, &smpo &vs, &pd, TYPE, valuelen, &value, &CC, &RC) Loop end MQPMO mqpmoの設定(バージョンの設定、メッセージ・ハンドルの受け渡し) MQPUT(Hcon, Hobj, &md, &pmo, messlen, buffer, &CC, &RC); MQDMHO dhmoの設定 MQDLTMH(Hcon, &Hmsg, &dmho, &CC, &RC); 10 <WebSphere MQ V7 Update Workshop> メッセージ・プロパティを参照するアプリケーションの流れ メッセージ・プロパティの参照 MQCRTMHでメッセージ・ハンドルを作成 メッセージ・ハンドルをMQGMOにセットし、MQGET MQINQMPでメッセージ・プロパティを参照 アプリケーション キュー・マネージャー MQCRTMH メッセージ・ ハンドルの作成 メッセージ・ ハンドル MQGMO MQGET MQCRTMH MQINQMP プロパティ付の メッセージをGET メッセージ・ ハンドル MQINTMQ メッセージ・ プロパティの参照 メッセージ・ プロパティの参照 メッセージ・ ハンドル 11 <WebSphere MQ V7 Update Workshop> メッセージ・プロパティの参照 コーディング・イメージ メッセージ・プロパティの参照 プロパティ付のメッセージ MQCMHO の設定 MQHMSG Hmsg; MQCRTMH(Hcon, MQCMHO, &Hmsg, &CC, &RC); MQGMO gmoの設定(バージョンの設定、メッセージ・ハンドルの受け渡し) MQGET(Hcon, Hobj, &md, &gmo, size, buffer, &messen, &CC, &RC); Loop MQIMPO impoの設定 MQPD pd の設定 MQCHARV inqnames; MQINQMP(Hcon, Hmsg, &impo, &inqnames, &pd, TYPE, size, value, &datalen, &CC, &RC) Loop end MQDLTMH(Hcon, &Hmsg, &dmho, &CC, &RC); 12 <WebSphere MQ V7 Update Workshop> MQPMO、MQGMOの設定 メッセージ・プロパティ使用時には、MQPMO、MQGMOにバージョンの指定が必要 MQPMO Version3 v7で新たに追加 Version、NewMsgHandle、Actionフィールド(プロパティ関連のフィールドを抜粋) MQPMO pmo; pmo.Version = MQPMO_VERSION_3; pmo.NewMsgHandle = Hmsg; MQGMO Version4 v7で新たに追加 Version、MsgHandle、Optionsフィールドを設定 MQGMO gmo; gmo.Version = MQGMO_VERSION_4; gmo.MsgHandle = Hmsg; gmo.Options += MQGMO_PROPERTIES_IN_HANDLE; 13 <WebSphere MQ V7 Update Workshop> v6アプリケーションとの互換性 v6のアプリケーションは変更することなく、メッセージ・プロパティ付のメッセージを MQRFH2形式でGETすることが可能 キューやチャネルのPROPCTL属性でメッセージ・プロパティーの扱い方を指定する キューの設定 メッセージをGETする際のメッセージ・プロパティの扱いを指定 MQGET時にMQGMOオプションで上書き設定が可能 チャネルの設定 メッセージを転送する際のメッセージ・プロパティの扱いを指定 「JMS関連のメッセージ・プロパティをMQRFH2で受け取る」、 「すべてのプロパティをMQRFH2として送信」といった指定が可能 v7 アプリケーション v6 アプリケーション MQPUT MQGET プロパティ付の メッセージをPUT MQRFH2ヘッダーに プロパティをセットしGET 14 <WebSphere MQ V7 Update Workshop> <参考>メッセージ・プロパティ関連属性 キュー属性PROPCTL ALTER QLOCAL( ) PROPCTL(COMPAT/ALL/FORCE/NONE) :メッセージ・ハンドルがセットされていた場合、すべてのメッセージ・プロパティはメッセージ・ハンドル 経由で取得される。セットされていない場合、すべてのメッセージ・プロパティはMQRFH2に格納される。 COMPAT :mcd、jms、usr、mqextから始まるメッセージ・プロパティが含まれていた場合、 すべてのメッセージ・プロパティがMQRFH2に格納される。それ以外の場合、すべてのメッセージ・プロパ ティは破棄される FORCE :メッセージ・ハンドルがMQGMOにセットされているかいないかに関係なく、 すべてのメッセージ・プロパティがMQRFH2 に格納される NONE :すべてのメッセージ・プロパティは破棄される ALL チャネル属性 ALTER CHANNEL( ) PROPCTL(COMPAT/ALL/NONE) 以下のチャネルに設定が可能 • SENDER • SERVER • CLUSTER SENDER • CLUSTER RECEIVER ALL:すべてのメッセージ・プロパティが運ばれる COMPAT: mcd、jms、usr、mqextから始まるメッセージ・プロパティが含まれていた場合、 すべてのメッセージ・プロパティが運ばれる。それ以外の場合、すべてのメッセージ・プロパティは破棄される NONE:すべてのメッセージ・プロパティは破棄される 15 <WebSphere MQ V7 Update Workshop> <参考>メッセージ・プロパティ関連の新規構造体 構造体 MQCMHO MQDMHO MQSMPO MQIMPO MQDMPO MQMHBO MQBMHO 説明 MQCRTMHコールの動作を指定する構造体 MQDLTMHコールの動作を指定する構造体 MQSETMPコールの動作を指定する構造体 MQINQMPコールの動作を指定する構造体 MQDLTMPコールの動作を指定する構造体 MQMHBUFコールの動作を指定する構造体 MQBUFMHコールの動作を指定する構造体 MQPD メッセージ・プロパティに関する動作を指定する構造体 16 <WebSphere MQ V7 Update Workshop> メッセージ・セレクター メッセージをブラウズすることなく指定したプロパティ値を持つメッセージだけを受信可能 キュー・マネージャー側で、条件に合うメッセージを選別し送信する アプリケーション側でブラウズする必要がなくなる 注意点 MsgId/CorrelIdとは違い、インデックスを用いて検索は行わない 大量にメッセージが滞留しているキューに対しセレクターを用いてMQGETする場合、 検索に時間がかかる可能性がある V6 アプリケーションでまずブラウズし、内容 に応じてメッセージをGET アプリケーション MQOPEN MQOO_BROWSE MQGET MQGMO_BROWSE_.. メッセージの内容を調べる Î 条件にあっていたらGET ・・・ ・・・ メッセージ・プロパティをセット V7 アプリケーション MQOPEN Product=MQ SelectionString=“Product=MQ” Product=WAS MQGET MQGET MQGET Product=WAS SelectionStringに一致する プロパティを持つメッセージが 送信される Product=MQ Product=WAS MQRC_NO_MSG_AVAILABLE 17 <WebSphere MQ V7 Update Workshop> メッセージ・セレクターの設定 MQGETで選択受信を行う場合 MQOD構造体(version 4)のSelectionString(MQCHARV構造体)フィールドに セレクター条件式を設定する MQCHARV構造体: 可変長の文字列を格納(v7で新規追加) char selection[STR_SIZE]; MQOD od; strcpy(selection,“Product = ‘MQ’"); od.Version = MQOD_VERSION_4; od.SelectionString.VSPtr=selection; od.SelectionString.VSLength=STR_SIZE; …. MQOPEN(Hcon, &od, O_optoins, &Hobj, &OpenCOde, &Reason); MQGET(Hcon, Hobj, &md, buflen, buffer, &messlen, &CompCode, &Reason); MQSUBで選択受信を行う場合 MQSB構造体のSelectionStringフィールドにセレクターを設定する char selection[STR_SIZE]; MQSD sd; strcpy(selection,“Product = ‘MQ’"); sd.SelectionString.VSPtr=selection; sd.SelectionString.VSLength=STR_SIZE; …… MQSUB(Hconn, &sd, Hobj, Hsub, &CompCode, &ReasonCode); 18 MQODをセットしてMQOPEN MQGETはこれまで通り <WebSphere MQ V7 Update Workshop> メッセージ・セレクターの設定 セレクター条件式の記述方法 プロパティ名 <比較演算式> リテラル 代表的なリテラル 文字列: ‘blue’ バイト文字列: “0x0AFC23” 数値:67、 -1818 近似数値: 6.2、57.9E2 ブール値: TRUE、 FALSE 比較演算式 =、>、>=、<、<=、<> 例1) プロパティ名Productの文字列の値が’MQ’: Product = ‘MQ’ 例2) プロパティ名StockPriceの数値の値が200以上: StockPrice >= 200 AND、ORを用いて条件式を接続することが可能 例) Type = ‘car’ AND color = ‘blue’ AND weight > 2500 19 <WebSphere MQ V7 Update Workshop> ブランク・ページ 20 <WebSphere MQ V7 Update Workshop> 非同期メッセージ受信 (コールバック機能) 21 <WebSphere MQ V7 Update Workshop> コールバック機能の導入 非同期的にメッセージを受信する機能 コールバック関数(処理ルーチン)をキュー・マネージャーに登録 キューにメッセージが到着すると、コールバック関数が呼び出される 複数キューに対してコールバック関数を登録することができる アプリケーションはメッセージの到着を待つために、処理をブロックする必要がなくなる アプリケーション キュー・マネージャー V6 アプリケーション MQGET wait メッセージを 処理・・ MQPUT キュー・マネージャー MQGET waitで メッセージの到着を待機 その間アプリケーションは 他の処理ができない(同期処理) アプリケーション コールバック関数の登録 V7 複数プロセス(スレッド)で 複数キューからの メッセージを待機 処理ルーチン登録 複数キューに対して コールバック関数の登録が可能 処理ルーチン登録 スレッド生成 アプリケーション コールバック関数を 呼び出し 22 処理継続 コールバック機能を起動後 処理の継続が可能 (非同期処理) ・・・ MQPUT コールバック関数 func1 メッセージの処理 : return コールバック開始 メッセージはキュー・マネージャーから 直接コールバック関数に渡される <WebSphere MQ V7 Update Workshop> コールバック機能 コールバック機能を開始するには下の2つの操作を行うことが必要 コールバック関数の登録(MQCBコール) コールバック機能の開始(MQCTLコール) コールバック機能関連の新規追加されたMQI MQCBコール 特定のオブジェクトハンドルに対して、コールバック関数の登録を行うために追加されたMQI 2タイプのコールバック関数が登録可能 –メッセージ・コンシューマー: 下の場合に呼び出される ・メッセージが到着 ・特定のキューのエラー発生時(MQGETが禁止された場合など) ・キュー・マネージャー全体に関するエラーが発生した場合 (キュー・マネージャーの停止、コネクションの切断など) –イベント・ハンドラー: キュー・マネージャー全体に関するエラーが発生した場合に限定されて呼び出される ※イベント・キューを監視する関数ではなく、上記の事象が発生した場合に呼び出される関数 MQCTLコール コールバック関数の制御を行うために追加されたMQI コールバック関数とは メッセージがキューに到着したときに、アプリケーションが開始したスレッドから呼び出される 処理ルーチン 下の2通りで実装可能 プログラムの関数 ダイナミックリンク・ライブラリ 23 <WebSphere MQ V7 Update Workshop> コールバック機能を用いた基本的なアプリケーションの流れ MQCB(Queue1, func1) コールバック関数の登録 MQCTL(MQOP_START) コールバック機能の開始 (マルチスレッド) MQCTL(MQOP_STOP) コールバック機能の停止 MQCONN MQOPEN(Queue1, hObj1) キュー・マネージャー システムが スレッドを生成 MQCB(Queue1,func1) 別スレッド MQCTL(MQOP_START) コールバック関数 MQPUT MessageConsumer() メッセージの処理 他の処理 return MQCTL(MQOP_STOP) メッセージが到着すると コールバック関数が 呼び出される 1メッセージづつ処理 MQDISC 24 <WebSphere MQ V7 Update Workshop> コールバック機能の制約 一つのコネクション・ハンドルに対して生成されるスレッドは一つのみ メッセージはキューに到着した順に、一メッセージずつ処理される 複数キューに対して、コールバック関数を登録していた場合も同様 複数のスレッドを生成し並行してメッセージを待機するためには、MQCONNを複数回 実行する必要がある キュー・マネージャー コールバック関数Aを登録 MQCB コールバック関数Bを登録 MQCB MQCTL ・・・ コールバック 機能開始 スレッド キューA キューAにPUTされた メッセージ MQPUT キューB ①キューAにPUT コールバック関数A ②キューBにPUT メッセージの処理 キューAにPUTされた メッセージを処理 return コールバック関数Bは コールバック関数Aが リターンするまで処理 されない キューBにPUTされた メッセージ MQPUT メッセージが到着した順番: キューA Î キューB コールバック関数B メッセージの処理 キューBにPUTされた メッセージを処理 return 25 <WebSphere MQ V7 Update Workshop> コールバック機能の制約 コールバック機能を開始後、コールバック関数を登録したコネクション・ハンドルを 通してMQI(MQCTL、MQDISC以外)を実行することはできない MQRC_HCONN_ASYNC_ACTIVEエラーが返る MQCTL、MQDISC以外のMQIを実行するためには、 MQCONNをもう一度実行する、もしくは、MQIを用いない処理を行う必要がある キュー・マネージャー MQCONN ・・・ コールバック関数登録 MQCB MQCTL MQPUT コールバック 機能開始 ・・・ MQPUT スレッド コールバック関数 MQGET MQRC_HCONN_ ASYNC_ACTIVE 26 <WebSphere MQ V7 Update Workshop> コールバック関数の登録/開始 コールバック機能を開始するための、最低限の設定 コールバック関数の登録:MQCBコール(New MQI) MQCB(Hconn, Operation, Hobj, CallbackDesc, MsgDesc, GetMsgOps, CompCode, Reason) 下のフィールドを設定(メッセージ・コンシューマーの場合) (MQLONG)OperationフィールドにMQOP_REGISTERを設定 (MQCBD)CallbackDesc構造体を設定 –(MQLONG) CallbackTypeにMQCBT_MESSAGE_CONSUMERを設定 –(MQPTR) CallbackFunctionにコールバック関数のポインタを設定 コールバック関数の開始/停止:MQCTLコール(New MQI) MQCTL(Hconn, Operation, ControlOpts, CompCode, Reason) 下のフィールドを設定 (MQLONG) OperationフィールドにMQOP_START/MQOP_STOPを設定 <参考>追加された構造体 MQCBD構造体:コールバック関数と、その動作を指定するための構造体 MQCTLO構造体:MQCTLコールの動作を指定するための構造体 MQCBC構造体:メッセージの情報や、コールバック機能の状態が格納される 27 <WebSphere MQ V7 Update Workshop> コールバック関数の登録/開始 サンプル MQCBD cbd = {MQCBD_DEFAULT}; /* Callback Descriptor MQCTLO ctlo= {MQCTLO_DEFAULT}; /* Control Options */ */ MQCBD構造体の宣言 MQCTLO構造体の宣言 ・・・・ /* Register a consumer */ cbd.CallbackFunction = MessageConsumer; コールバック関数のセット MQCB(Hcon, MQOP_REGISTER, &cbd, Hobj, &md, &gmo, &CompCode, コールバック関数の登録 &Reason); if (CompCode == MQCC_FAILED) { printf("MQCB ended with reason code %d¥n", Reason); } ・・・・・ MQCTL(Hcon, MQOP_START, &ctlo, &CompCode, &Reason); コールバック関数の開始 if (CompCode == MQCC_FAILED) { printf("MQCTL ended with reason code %d¥n", Reason); } ・・・・・・ MQCTL(Hcon, MQOP_START, &ctlo, &CompCode, &Reason); if (CompCode == MQCC_FAILED) { printf("MQCTL ended with reason code %d¥n", Reason); } ※v7付属のサンプル・アプリケーションより 28 コールバック関数の停止 <WebSphere MQ V7 Update Workshop> コールバック関数の実装 コールバック関数は下の2通りで実装可能 プログラムの関数 ダイナミックリンク・ライブラリ プロトタイプにしたがって、関数を定義(関数名は任意) • メッセージ・コンシューマーのプロトタイプ MQLONG MessageConsumer( MQHCONN MQMD * MQGMO * MQBYTE * MQCBC * hConn, pMsgDesc, pGetMsgOpts, Buffer, pContext ){ MQHCONN MQMD MQGMO void * MQCBC hConn, MsgDesc, getMsgOpts, Buffer, Context ){ ・・・・ return 0; } • イベント・ハンドラーのプロトタイプ MQLONG EventHandler( ・・・・ return 0; } 29 <WebSphere MQ V7 Update Workshop> コールバック関数の実装 メッセージの情報や、コールバック機能の状態で処理を場合分けできる CallType(MQCBC構造体)で判別 メッセージと一緒にコールバック関数に渡される構造体 「メッセージが到着した場合」、「キューから正常にメッセージをGETできなかった場合」 といった場合分けが可能 メインスレッドにエラー・コードが返るのではなく、MQCBCを通してコールバック関数に エラー・コードが返る コールバック関数の中で、エラーをハンドルする必要がある エラー発生時にコールバック関数の中からMQCTL(STOP)を実行することが可能 コールバック関数の中でMQBACKを実行することも可能 30 <WebSphere MQ V7 Update Workshop> コールバック関数が受け取るメッセージの長さ MQCBD構造体のMaxMsgLengthの変数でコールバック関数が受け取るメッセージの 長さを指定 MaxMsgLength(バイト数)を指定した場合 MaxMsgLengthを超えるメッセージの場合、コールバック関数は下の理由コードとともに、 MaxMsgLengthバイト分のメッセージを受け取る –MQRC_TRUNCATED_MASG_FAILED (GetMessageOptionの指定なし) –MQRC_TRUNCATED_MSG_ACCEPTED ( MQGMO_ACCEPT_TRUNCATED_MSGを指定) 実際のメッセージ長はMQCBC構造体のDataLength変数に格納される MQCBD_FULL_MSG_LENGTHを指定した場合 メッセージは切り取られることなく、バッファー長が調節される もし、システムに十分なメモリ領域が残されていない場合、 MQRC_STORAGE_NOT_AVAILABLE エラーコードが返る Îアプリケーション側でのバッファサイズの予測が不要 31 <WebSphere MQ V7 Update Workshop> コールバック関数 サンプル MQLONG MessageConsumer(MQHCONN hConn, MQMD * pMsgDesc, MQGMO * pGetMsgOpts, MQBYTE * Buffer, MQCBC * Context) { プロトタイプに沿って 関数を作成 MQCBC.CallTypeで 処理を場合分け switch(pContext->CallType) { case MQCBCT_MSG_REMOVED: case MQCBCT_MSG_NOT_REMOVED: メッセージが到着 したとき if (pContext->Reason) printf("Message Call (%d Bytes) : Reason = %d¥n", MQCBCに応答 コード、データ長を表示 pContext->DataLength,pContext->Reason); else printf("Message Call (%d Bytes) :¥n", pContext->DataLength); ・・メッセージを表示 break; case MQCBCT_EVENT_CALL: printf("Event Call : Reason = %d¥n",pContext->Reason); break; default: printf("Calltype = %d¥n",pContext->CallType); break; } return 0; } ※v7付属のサンプル・アプリケーションより 32 エラーが発生した 場合 <WebSphere MQ V7 Update Workshop> <参考>シングルスレッドでコールバック機能を使用 シングルスレッドアプリケーション MQCONN MQCTL(MQOP_START_ WAIT) コールバック機能の開始 (シングルスレッド) MQOPEN(Queue1, hObj1) MQCB(Queue1,func1) MQCTL(MQOP_START WAIT) メッセージが到着すると コールバック関数が 呼び出される アプリと同じ スレッドで動作 キュー・マネージャー コールバック関数 MessageConsumer() MQPUT メッセージの処理 コールバック機能が 停止されるまで 制御は戻らない MQCTL(MQOP_STOP) コールバック機能を停止 するには、コールバック 関数の中からMQCTL コールを発行する 必要ことが必要 1メッセージづつ処理 return MQDISC 33 <WebSphere MQ V7 Update Workshop> ブランク・ページ 34 <WebSphere MQ V7 Update Workshop> マークを用いたメッセージブラウズ機能 35 <WebSphere MQ V7 Update Workshop> メッセージブラウズ機能の拡張 ブラウズ時にメッセージにマークを付ける機能が追加 次回ブラウズ時に、メッセージを参照済みと認識 Î「マークがついていないメッセージを先頭からブラウズする」という処理が可能になる マークを指定し、メッセージをGETすることが可能 複数アプリケーションでマークを共有することも可能 ブラウズ・アプリケーション メッセージにマークがつく MQGET ブラウズ+マーク メッセージ1 メッセージ2 メッセージ3 MQGET ブラウズ+マーク MQGET ブラウズ+マーク MQGET マークが 9 メッセージをGET の 新規メッセージブラウズ機能のメリット メッセージの読み飛ばしを防ぐことができる 複数アプリケーションでの2重読みを防ぐことができる 36 9 9 9 <WebSphere MQ V7 Update Workshop> v6までのカーソルによるブラウズ機能の問題点 「すべてのメッセージを1回ずつブラウズしたい」という要件がある場合 メッセージの読み飛ばしが発生する場合がある コミット済のメッセージと、未コミットメッセージが混在している メッセージに優先付けをしている メッセージがバックアウトされた FASTチャネルを使用しているとき、パーシステント、ノン・パーシステント・メッセージが 混在している Î BROWSE_FIRSTでカーソルをキューの先頭に戻す必要がある ④メッセージ2をブラウズ (メッセージ1はコミットされていないため、 キューには存在していないように見える) 送信アプリA MQPUT ①メッセージ1をPUT syncpoint メッセージ2 MQPUT syncpoint MQCOMIT MQCOMIT 受信アプリケーション メッセージ1 送信アプリB NO_MSG_AVAILABLE ②メッセージ2をPUT ⑤メッセージ1をコミット ③メッセージ2をコミット MQGET MQGMO_BROWSE_NEXT MQGET MQGMO_BROWSE_NEXT ⑥メッセージ1がコミットされても、 カーソルはメッセージを並び順で処理するため、 メッセージ1は読み飛ばされる 37 <WebSphere MQ V7 Update Workshop> マークを用いたメッセージブラウズ機能 メッセージ・トークンを利用し、メッセージにマークをつける メッセージ Token 9 メッセージ・トークンはキュー内でユニークなIDとしてメッセージに付与される MQGMO v3のバイナリフィールド メッセージがキューにある時のみ有効で、キューマネージャーの再起動で引き継がれない マークのついていないメッセージを限定してブラウズすることが可能 マークのついたメッセージはブラウズしない MQGMO_UNMARKED_BROWSE_MSGオプションをブラウズ時に指定 トークンを指定して、マークのついたメッセージをGETすることが可能 MQGMO_MATCH_MSG_TOKENオプションをブラウズ時に指定 マークのついたメッセージがキューにない場合、MQRC_NO_MSG_AVAIRABLEが返る メッセージ・トークンを渡し、別アプリケーションで該当メッセージをGETすることが可能 MQGET MQGMO.MsgToken 9 MQMO_MATCH_MSG_TOKEN MQGET waitでメッセージを待つこともできる 38 メッセージ1 メッセージ2 メッセージ3 9 9 9 <WebSphere MQ V7 Update Workshop> マークの種類 下の2種類のマークを指定することができる 単一アプリケーションで使用するマーク(他のアプリケーションがつけたマークは認識しない) マークは各アプリケーションごとに用意される MQGMO_MARK_BROWSE_HANDLEオプションをブラウズ時に指定する アプリケーションB アプリケーションA 9 9 複数アプリケーションで共有するマーク(他のアプリケーションがつけたマークも認識) マークは共有される + MQGMO_MARK_BROWSE_CO_OPオプションをブラウズ時に指定する MQOO_CO_OPオプションを付けてキューをオープン アプリケーションA アプリケーションB 9 9 39 <WebSphere MQ V7 Update Workshop> 新規追加されたオプション マークを共有しない場合、マーク操作に用いるオプション MQGMOオプション MQGMO_MARK_BROWSE_HANDLE MQGMO_UNMARK_BROWSE_HANDLE 説明 メッセージにマークをつける メッセージのマークをはずす MQGMO_UNMARKED_BROWSE_MSG マークがついていないメッセージをブラウズする マークを共有する場合、マーク操作に用いるオプション MQOOオプション MQOO_CO_OP 説明 下のMQGMOオプション指定時にマークは共有される MQGMO_MARK_BROWSE_CO_OP MQGMO_UNMARK_BROWSE_CO_OP MQGMO_UNMARKED_BROWSE_MSG MQGMOオプション MQGMO_MARK_BROWSE_CO_OP MQGMO_UNMARK_BROWSE_CO_OP MQGMO_UNMARKED_BROWSE_MSG 40 説明 MQOO_CO_OPでオープンされたメッセージが共有 するマークをつける MQOO_CO_OPでオープンされたメッセージが共有 するマークをはずす マークがついていないメッセージをブラウズする <WebSphere MQ V7 Update Workshop> マークが外されるタイミング マークの共有、非共有にかかわらず、下のタイミングでマークは外れる MQGETによってキューからメッセージが取り出されるとき MQGETがロールバックされたとき Expiry満了によりメッセージが削除されたとき QMGR属性MARKINTの設定時間を過ぎたとき ALTER QMGR MARKINT( integer ¦ NOLIMIT) NOLIMIT: MAKRINT属性によるマークの除去はなし integer(ミリ秒): integer秒経過後、マークが外される 新規追加されたQMGR属性 デフォルト5000(ミリ秒) 下の場合、マークの共有、非共有の違いにより、異なるタイミングでマークが外れる マークを共有しない場合 オブジェクト・ハンドルが閉じられたとき MQGMO_UNMARK_BROWSE_HANDLEオプション付でブラウズしたとき マークを共有する場合 MQOO_CO_OPでオープンしているすべてのオブジェクト・ハンドルが閉じられたとき MQGMO_UNMARK_BROWSE_CO_OPオプション付でブラウズしたとき 41 <WebSphere MQ V7 Update Workshop> 一般的なアプリケーションの例 キューの先頭から(BROWSE_FIRST)、マークされていないメッセージを読み込む マークは共有しない アプリケーションの流れ キューの先頭からマークがついていないメッセージをブラウズ 一度読み込んだメッセージにマークをつける メッセージの内容に応じて MQGMO_MATCH_MSG_TOKENオプションでマークを指定し、メッセージをGETする v6までのブラウズ機能と比較したメリット 常にキューの先頭から、メッセージを読み飛ばすことなくブラウズすることが可能 ⑥メッセージ1がコミットされた後、 マークのついていないメッセージ1が ブラウズされる アプリケーション ①メッセージ1をPUT MQPUT メッセージ1 syncpoint MQPUT syncpoint MQCMIT MQCMIT メッセージ2 9 ②メッセージ2をPUT ③メッセージ2をコミット ブラウズアプリケーション MQOPEN Loop MQGET MQOO_BROWSE MQGMO_BROWSE_FIRST + MQGMO_UNMARKED_BROWSE_MSG + MQGMO_MARK_BROWSE_HANDLE MQGET ⑤メッセージ1をコミット ④メッセージ2をブラウズ Îマークをつける MQPUT、MQCMITが入れ子になった 場合のアプリケーションの動作 MQGMO_MATCH_MSG_TOKEN Loop end MQGMO_MATCH_MSG_TOKEN オプションでマークのついたメッセージをGET 42 <WebSphere MQ V7 Update Workshop> マークを共有するアプリケーションの例 複数アプリケーションでマークを共有 アプリケーションの流れ キューの先頭からマークがついていないメッセージをブラウズ 他のアプリケーションがつけたマークを含む 一度読み込んだメッセージにマークをつける メッセージの内容に応じて MQGMO_MATCH_MSG_TOKENオプションでマークを指定し、メッセージをGETする ①一度読んだメッセージに マークをつける アプリケーション MQOPEN MQGET アプリケーション MQOO_BROWSE MQOO_CO_OP メッセージ1 9 MQGMO_BROWSE_FIRST + MQGMO_UNMARKED_BROWSE_MSG + MQGMO_MARK_BROWSE_CO_OP メッセージ2 MQGET MQOPEN MQOO_BROWSE MQOO_CO_CP MQGET BROWSE_FIRST + UNMARKED_BROWSE_MSG + MARK_BROWSE_CO_OP MQGMO_MATCH_MSG_TOKEN ②他のアプリケーションが マークしたメッセージはブラウズされない 43