Hitachi

OpenTP1 Version 7 OpenTP1 メッセージキューイング機能 TP1/Message Queue プログラム作成リファレンス


MQPUT命令 − メッセージの登録

〈このページの構成〉

機能

MQPUT命令で,メッセージをキューまたは配布リストへ登録できます。このとき,キューはオープンされている必要があります。

形式

C言語の場合

MQPUT(MQHCONN Hconn, MQHOBJ Hobj, PMQVOID MsgDesc,
      PMQVOID PutMsgOpts, MQLONG BufferLength,
      PMQVOID Buffer, PMQLONG CompCode, PMQLONG Reason)

COBOL言語の場合

CALL 'MQPUT' USING HCONN, HOBJ, MSGDESC, PUTMSGOPTS,
                BUFFERLENGTH, BUFFER, COMPCODE, REASON.

引数

● Hconn(MQHCONN型) −input

コネクションハンドルです。

キューマネジャへの接続を示すハンドルです。MQCONN命令の戻り値を指定してください。

● Hobj(MQHOBJ型) −input

オブジェクトハンドルです。

メッセージを登録するキューを示すハンドルです。MQOO_OUTPUTオプションを指定したMQOPEN命令の戻り値を指定してください。

● MsgDesc(MQMD構造体) −input/output

メッセージ記述子です。

送信するメッセージの属性を記述する構造体です。また,登録後のメッセージに関する情報が返されます。

詳細については,「1. データタイプ」の「MQMD構造体 − メッセージ記述子」を参照してください。

アプリケーションがバージョン1のMQMD構造体を指定すると,返却されるメッセージは,バージョン2のMQMD構造体にだけ存在するフィールドの値を指定するために,アプリケーションメッセージデータの前にMQMDE構造体を付加できます。そのとき,MQMDE構造体が存在することを示すために,MQMD構造体のFormatフィールドには,MQFMT_MD_EXTENSIONを設定しなければなりません。

詳細については,「1. データタイプ」の「MQMDE構造体 − メッセージ記述子の拡張」を参照してください。

● PutMsgOpts(MQPMO構造体) −input/output

メッセージ登録オプションです。

詳細については,「1. データタイプ」の「MQPMO構造体 − メッセージ登録オプション」を参照してください。

● BufferLength(MQLONG型) −input

メッセージデータを格納したバッファのバイト長です。

0も指定できます。このとき,アプリケーションデータのないメッセージを登録するものとみなされます。BufferLengthの上限は状況によって異なります。

  • あて先キューが共用キューの場合,上限は63キロバイト(64512バイト)です。

  • あて先キューがローカルキューの場合,またはローカルキューの別名を使用している場合は,ローカルキューまたはキューマネジャのMaxMsgLength属性のうち,小さい方の値を超えて指定できません。

  • あて先キューがリモートキューの場合,またはリモートキューの別名を使用している場合は,次に示すローカルキューまたはキューマネジャのMaxMsgLength属性のうち,小さい方の値を超えて指定できません。

    1. ローカルキューマネジャで一時的に格納するために使用される転送キュー

    2. ローカルキューからあて先キューまでの経路で仲介するキューマネジャで使用される転送キュー

    3. あて先キューマネジャで使用されるあて先キュー

    なお,メッセージが転送キューに格納されるとき,メッセージに付加情報が追加されます。このため,送信できるアプリケーションデータの量が少なくなります。BufferLength引数の値を決めるときは,転送キューのMaxMsgLength属性の値からMQ_MSG_HEADER_LENGTHのバイト数を引いた値を参考にしてください。

    注意事項

    上記の1.の場合だけ,メッセージの登録直後にバッファ長のエラー(理由コードMQRC_MSG_TOO_BIG_FOR_QまたはMQRC_MSG_TOO_BIG_FOR_Q_MGR)が判明します。2.,3.の場合は,登録直後はエラーが判明しません。2.,3.でエラーが判明した場合,仲介するキューマネジャまたはあて先キューマネジャのデッドレターキューに,メッセージが転送されます。送信側で要求している場合は,エラー発生時に報告メッセージが生成されます。

● Buffer(MQBYTE型×BufferLength) −input

メッセージデータを格納したバッファです。バッファには,メッセージ中のデータに適したバウンダリ調整が必要です。多くのメッセージ(MQヘッダ構造体のあるメッセージを含む)には4バイト単位の調整が適していますが,より厳しい調整が必要なメッセージもあります。例えば,64ビット2進整数を含めるメッセージには8バイト単位のバウンダリ調整が必要です。

バッファ内に文字または数値がある場合,MsgDesc引数のCodedCharSetIdフィールドとEncodingフィールドに,適切な値を指定してください。これらの値によって,受信側でデータを適切な文字セットとマシンコード形式に変換できます。

注意事項

MQPUT命令のそのほかの引数は,ローカルキューマネジャの文字セットとマシンコード形式,つまり,ローカルキューのCodedCharSetId属性とMQENC_NATIVEで指定してください。

C言語では,この引数をvoid型のポインタとして指定します。したがって,どんなデータタイプのアドレスでも,引数として指定できます。

BufferLength引数に0を指定した場合,Buffer引数は参照されません。したがって,C言語のプログラムでは,この引数のアドレスとしてヌルを指定できます。

● CompCode(MQLONG型) −output

完了コードです。

次のどれかが返されます。

  • MQCC_OK:成功

  • MQCC_WARNING:警告(一部成功)

  • MQCC_FAILED:失敗

● Reason(MQLONG型) −output

理由コードです。

CompCode引数がMQCC_OKの場合

理由コード

数値

意味

MQRC_NONE

0

理由コードはありません。

CompCode引数がMQCC_WARNINGの場合

理由コード

数値

意味

MQRC_INCOMPLETE_GROUP

2241

メッセージグループが完全ではありません。

MQRC_INCOMPLETE_MSG

2242

論理メッセージが完全ではありません。

MQRC_INCONSISTENT_PERSISTENCE

2185

永続性指定が矛盾しています。

MQRC_INCONSISTENT_UOW

2245

コミット単位の指定が矛盾しています。

MQRC_MULTIPLE_REASONS

2136

複数の理由コードが返されました。

MQRC_PRIORITY_EXCEEDS_MAXIMUM

2049

メッセージ優先度が最大値を超えています。

MQRC_UNKNOWN_REPORT_OPTION

2104

メッセージ記述子中の報告オプションを認識できません。

CompCode引数がMQCC_FAILEDの場合

理由コード

数値

意味

MQRC_BUFFER_ERROR

2004

バッファの引数が不正です。

MQRC_BUFFER_LENGTH_ERROR

2005

バッファ長の引数が不正です。

MQRC_CLUSTER_RESOLUTION_ERROR

2189

クラスタ名称の解決に失敗しました。

MQRC_CLUSTER_RESOURCE_ERROR

2269

クラスタリソースのエラーです。

MQRC_CONTEXT_HANDLE_ERROR

2097

参照先のキューハンドルにコンテキストが保存されていません。

MQRC_CONTEXT_NOT_AVAILABLE

2098

参照先のキューハンドルのコンテキストが不正です。

MQRC_DH_ERROR

2135

配布リストの構造体が不正です。

MQRC_EXPIRY_ERROR

2013

メッセージ保持時間が不正です。

MQRC_FEEDBACK_ERROR

2014

報告メッセージ返答コードが不正です。

MQRC_HCONN_ERROR

2018

コネクションハンドルが不正です。

MQRC_HOBJ_ERROR

2019

オブジェクトハンドルが不正です。

MQRC_INCOMPLETE_GROUP

2241

メッセージグループが完全ではありません。

MQRC_INCOMPLETE_MSG

2242

論理メッセージが完全ではありません。

MQRC_INCONSISTENT_PERSISTENCE

2185

永続性指定が矛盾しています。

MQRC_INCONSISTENT_UOW

2245

コミット単位の指定が矛盾しています。

MQRC_MD_ERROR

2026

メッセージ記述子が不正です。

MQRC_MDE_ERROR

2248

メッセージ記述子の拡張子が不正です。

MQRC_MISSING_REPLY_TO_Q

2027

応答キューがありません。

MQRC_MSG_FLAGS_ERROR

2249

メッセージフラグが不正です。

MQRC_MSG_SEQ_NUMBER_ERROR

2250

メッセージシーケンス番号が不正です。

MQRC_MSG_TOO_BIG_FOR_Q

2030

メッセージ長がキューに定義された最大値を超えています。

MQRC_MSG_TYPE_ERROR

2029

メッセージ記述子中のメッセージタイプが不正です。

MQRC_MULTIPLE_REASONS

2136

複数の理由コードが返されています。

MQRC_NO_DESTINATIONS_AVAILABLE

2270

利用可能なあて先キューが存在しません。

MQRC_NOT_OPEN_FOR_OUTPUT

2039

キューが登録用にオープンされていません。

MQRC_NOT_OPEN_FOR_PASS_ALL

2093

キューが全コンテキスト引き渡し用にオープンされていません。

MQRC_NOT_OPEN_FOR_PASS_IDENT

2094

キューが識別コンテキスト引き渡し用にオープンされていません。

MQRC_NOT_OPEN_FOR_SET_ALL

2095

キューが全コンテキスト設定用にオープンされていません。

MQRC_NOT_OPEN_FOR_SET_IDENT

2096

キューが識別コンテキスト設定用にオープンされていません。

MQRC_OBJECT_DAMAGED

2101

オブジェクトが破損しています。

MQRC_OFFSET_ERROR

2251

メッセージセグメントのオフセットが不正です。

MQRC_OPEN_FAILED

2137

キューのオープンに失敗しました。

MQRC_OPTIONS_ERROR

2046

オプションが不正です。または,指定されていません。

MQRC_ORIGINAL_LENGTH_ERROR

2252

元のメッセージの長さが不正です。

MQRC_PCF_ERROR

2149

PCF構造体が不正です。

MQRC_PERSISTENCE_ERROR

2047

メッセージ永続性が不正です。

MQRC_PERSISTENT_NOT_ALLOWED

2048

キューは永続メッセージをサポートしていません。

MQRC_PMO_ERROR

2173

メッセージ登録オプションの構造体が不正です。

MQRC_PMO_RECORD_FLAGS_ERROR

2158

メッセージ登録レコードのフラグが不正です

MQRC_PRIORITY_ERROR

2050

メッセージ優先度が不正です。

MQRC_PUT_INHIBITED

2051

指定されたキューへの登録は禁止されています。

MQRC_PUT_MSG_RECORDS_ERROR

2159

メッセージ登録レコードが不正です。

MQRC_Q_DELETED

2052

キューが削除されています。

MQRC_Q_FULL

2053

キューが満杯です。

MQRC_Q_SPACE_NOT_AVAILABLE

2056

キューに対応するディスクに空き領域がありません。

MQRC_RECS_PRESENT_ERROR

2154

不正なレコードが存在します。

MQRC_REPORT_OPTIONS_ERROR

2061

メッセージ記述子中の報告オプションが不正です。

MQRC_RESOURCE_PROBLEM

2102

システム資源が不足しています。

MQRC_RESPONSE_RECORDS_ERROR

2156

応答レコードが不正です。

MQRC_SEGMENT_LENGTH_ZERO

2253

メッセージセグメント長が0です。

MQRC_STORAGE_NOT_AVAILABLE

2071

記憶容量が不足しています。

MQRC_SYNCPOINT_NOT_AVAILABLE

2072

同期点処理はできません。

MQRC_UNEXPECTED_ERROR

2195

予期しないエラーが発生しました。

MQRC_UOW_NOT_AVAILABLE

2255

コミット単位ではキューマネジャを使用できません。

MQRC_WRONG_MD_VERSION

2257

MQMD構造体で指定されたバージョンが誤っています。

詳細は,「付録B.2 理由コード」を参照してください。

注意事項

  1. キューへメッセージを登録する命令には,MQPUT命令とMQPUT1命令の二つがあります。これらの命令は,状況に応じて使い分けてください。

    • MQPUT命令は,同じキューへ複数のメッセージを登録するときに使用します。

      この方法では,始めにMQOO_OUTPUTオプションを指定してMQOPEN命令を呼び出します。次に,MQPUT命令を一回またはそれ以上呼び出してメッセージを登録してください。最後にMQCLOSE命令を呼び出して,キューをクローズします。この方法でメッセージを登録すると,MQPUT1命令を繰り返して呼び出すよりも効率的です。

    • MQPUT1命令は,あるキューへメッセージを一つだけ登録するときに使用します。

      この方法では,一回の呼び出しでMQOPEN命令,MQPUT命令,およびMQCLOSE命令を兼ねます。このため,命令の呼び出しを少なくできます。

  2. アプリケーションがメッセージグループを使用しないで,連続するメッセージを同じキューに登録する場合,特定の条件が満たされれば,メッセージの順序が保持されます。ローカルあて先キューとリモートあて先キューの両方に適用される条件と,リモートあて先キューだけに適用される条件があります。

    ローカルあて先キューおよびリモートあて先キューに適用される条件

    • すべてのMQPUT命令が同じトランザクション内にある。またはすべてトランザクション内にないこと

      メッセージが一つのトランザクション内で特定のキューに登録されるとき,他アプリケーションからのメッセージがキュー上の連続するメッセージに混じることがあるので注意してください。

    • すべてのMQPUT命令が同じオブジェクトハンドルHobjを使用すること

      環境によっては,異なるオブジェクトハンドルを使用しても,メッセージの順序が保持されることがあります。ただし,命令が同じアプリケーションから発行されるものとします。

    • メッセージがすべて同じメッセージ優先度であること

    リモートあて先キューに適用される追加の条件

    • 送信側のキューマネジャからあて先キューマネジャへの送信経路が一つしかないこと

      連続するメッセージの一部のメッセージが異なる送信経路を使用する可能性がある場合(例えば,再構成,トラフィック分散またはメッセージサイズに基づく経路選択の場合),あて先キューマネジャでのメッセージの順序は保証されません。

    • 送信側,中間またはあて先キューマネジャで,メッセージが一時的にデッドレターキューに登録されないこと

      一つ以上のメッセージが一時的にデッドレターキューに登録される場合(例えば,転送キューまたはあて先キューが一時的に満杯などが原因の場合),あて先キューに到着するメッセージは順序とおりでないことがあります。

    • メッセージがすべて永続的メッセージであるか,またはすべて非永続メッセージであること

      送信側キューマネジャとあて先キューマネジャ間の送信経路にあるチャネルのNonPersistentMsgSpeed属性がMQNPMS_FASTに設定される場合,非永続メッセージが永続メッセージに先行することがあります。その結果,非永続メッセージに対する永続メッセージの順序が保持されないことがあります。しかし,永続メッセージ間および非永続メッセージ間の順序は保持されます。

    これらの条件が満たされない場合,メッセージグループを使用してメッセージの順序を保持できます。しかし,送信側アプリケーションと受信側アプリケーションの両方について,メッセージグループを使用できる必要があることに注意してください。メッセージグループについては,次に示す項目を参照してください。

    • MQMD構造体のMsgFlagsフィールド

    • MQPMO構造体のMQPMO_LOGICAL_ORDERオプション

    • MQGMO構造体のMQGMO_LOGICAL_ORDERオプション

  3. 配布リストを使用するときは,次の点に注意してください。

    • メッセージは,バージョン1またはバージョン2のMQPMO構造体を使用して配布リストに登録できます。バージョン1のMQPMO構造体を使用する場合,またはRecsPresentフィールドが0であるバージョン2のMQPMO構造体を使用する場合,アプリケーションは登録メッセージレコードや,応答レコードを指定できません。この場合,メッセージが配布リストのあるキューに送信が成功して,ほかのキューへの送信が失敗したとき,エラーとなったキューを特定できません。アプリケーションによって登録メッセージレコードや応答レコードが指定される場合,VersionフィールドはMQPMO_VERSION_2でなければなりません。

      バージョン2のMQPMO構造体は,RecsPresentフィールドが0であれば,配布リストではない単一のキューにメッセージを送信する場合も使用できます。

    • CompCode引数およびReason引数は,次のように設定されます。

      ・配布リストのキューへ登録が,同じ方法で,すべて成功,または失敗した場合,完了コードおよび理由コードは,共通の結果を記述するように設定されます。MQRR構造体がアプリケーションで指定されている場合は,応答レコードは設定されません。

      例えば,すべての登録が成功した場合,完了コードはMQCC_OK,理由コードはMQRC_NONEに設定されます。すべてのキューが登録禁止になっているため,すべての登録が失敗する場合,引数はMQCC_FAILEDとMQRC_PUT_INHIBITEDに設定されます。

      ・配布リストのキューへの登録が同じ方法で,部分的に成功または失敗した場合は次のとおりです。

      −少なくとも一つの登録が成功していれば完了コードはMQCC_WARNINGが設定されます。すべてが失敗するとMQCC_FAILEDが設定されます。

      −理由コードの引数は,MQRC_MULTIPLE_REASONSに設定されます。

      −応答レコードがアプリケーションによって指定されている場合は,配布リストのキューに対して個別の完了コードと理由コードを設定します。

      あて先のオープンに失敗したために登録に失敗した場合,応答レコードのフィールドはMQCC_FAILEDおよびMQRC_OPEN_FAILEDに設定されます。そのあて先はInvalidDestCountフィールドに記述されます。

    • 配布リストのあて先がローカルキューに受信される場合,メッセージは通常の形式でキューに登録されます。配布リストメッセージではありません。複数のあて先が同じローカルキューに受信される場合,一つのメッセージがあて先キューに登録されます。

      配布リストのあて先がリモートキューに受信される場合,メッセージは転送キューに登録されます。幾つかのあて先が同じ転送キューに受信される場合,あて先を含んだ配布リストメッセージは,そのあて先がアプリケーションに指定されたあて先リストと隣接していなくても,転送キューに登録されます。ただし,これは転送キューが配布リストメッセージをサポートしているときだけ可能となります。詳細は,「3. オブジェクトの属性」の「キューの属性」のDistLists属性を参照してください。

      転送キューが配布リストをサポートしていないとき,通常の形式のメッセージを複写したものが,その転送キューを使用するそれぞれのあて先に対する転送キューに登録されます。

      アプリケーションメッセージを含んだ配布リストが転送キューよりも大きい場合,配布リストメッセージはさらに小さな配布リストメッセージに分割されます。分割された配布リストメッセージは,それぞれ幾つかのあて先を持っています。アプリケーションデータだけがキューに格納できれば,キューマネジャは配布リストメッセージをまったく使用しないで,その転送キューを使用するあて先に,通常の形式でメッセージの複写を生成します。

      例えば,アプリケーションがMQPRI_PRIORITY_AS_Q_DEF,MQPER_PERSISTENCE_AS_Q_DEFを指定している場合など,異なるあて先が異なるメッセージ優先度やメッセージ永続性を持っている場合,メッセージは同じ配布リストメッセージに必要ありません。その代わり,キューマネジャは,異なる優先度および永続性の値に対応するために必要な数の配布リストメッセージを生成します。

    • 配布リストへ登録した結果は,次のどれかです。

      ・単一の配布リストメッセージ

      ・分割された配布リストメッセージの数

      ・配布リストメッセージと通常のメッセージの混在

      ・通常のメッセージだけ

      上記のどの結果になるかは次に示す理由によります。

      ・リストのあて先が,ローカル,リモート,または混在している。

      ・あて先が,同じメッセージ優先度とメッセージ永続性となっているかどうか。

      ・転送キューが配布リストメッセージを保持できるかどうか。

      ・転送キューの最大メッセージ長が,配布リスト形式のメッセージに対応する大きさかどうか。

      上記のどの原因が発生したとしても,物理メッセージ,つまり登録したメッセージまたは配布リストメッセージは,次に示す場合は,ただ一つのメッセージとしてカウントされます。

      ・アプリケーションがトランザクションの最大メッセージ数を超えている,または最大メッセージ数を超えているかどうかをチェックする場合

      最大メッセージ数の詳細については「3. オブジェクトの属性」の「キューマネジャの属性」のMaxUncommittedMsgs属性を参照してください。

      ・トリガ条件を満たしているかどうかをチェックする場合

      ・キューの登録数を加算し,その値がキューの最大登録数を超えるかどうかをチェックする場合

    • 例えば,解決パスが変更された場合など,キューが個別にオープンされるとハンドルが不正になるようにキュー定義が変更されても,配布リストのハンドルは不正になりません。しかし,次のMQPUT命令によって,その配布リストのハンドルが使用されたキューのオープンは失敗します。

  4. アプリケーションメッセージデータの開始位置で,メッセージが一つ以上のMQヘッダ構造体と同時に登録された場合,キューマネジャはヘッダ構造体が正しいかどうかをチェックします。キューマネジャがエラーを検出すると,命令は適当な理由コードで失敗します。実行されるチェックの方法は,存在する構造体によって異なります。

    • バージョン2以降のMQMD構造体がMQPUTまたはMQPUT1命令で使用される場合にだけ,チェックが実行されます。メッセージデータの開始位置にMQMDE構造体があっても,バージョン1のMQMD構造体が使用されている場合,チェックは実行されません。

    • ローカルキューマネジャによってサポートされない構造体,およびメッセージ中で最初のMQDLH構造体に続く構造体は,有効性を確認されません。

    • MQDHおよびMQMDE構造体の有効性は,キューマネジャによって完全に確認されます。

    • ほかの構造体の有効性は,キューマネジャによって部分的に確認されます(すべてのフィールドが確認されるのではありません)。

    キューマネジャによって実行される一般的なチェックには,次に示す項目が含まれます。

    • StrucIdフィールドが有効であること

    • Versionフィールドが有効であること

    • StrucLengthフィールドには,構造体およびその一部である可変長データの格納に十分な大きさの値が指定されていること

    • CodedCharSetIdフィールドは,ゼロまたは無効な負の値でないこと

      MQCCSI_DEFAULT,MQCCSI_EMBEDDED,MQCCSI_Q_MGRおよびMQCCSI_UNDEFINEDは,ほとんどのMQヘッダ構造体で無効です。

    • 命令のBufferLength引数には,構造体の格納に十分な大きさの値が指定されていること

      メッセージの末尾を超えて構造体を拡張できません。

    構造体についての一般的なチェックに加えて,次に示す条件が満たされている必要があります。

    • PCFメッセージの構造体での長さの和は,MQPUT命令またはMQPUT1命令のBufferLength引数によって指定された長さと等しくなければなりません。PCFメッセージは,次のフォーマット名称のどれかを持つメッセージです。

       MQFMT_ADMIN

       MQFMT_EVENT

       MQFMT_PCF

    • MQ構造体は,省略された構造体が許可される次の場合を除いて,省略しないでください。

      報告メッセージであるメッセージ

      PCFメッセージ

      MQDLH構造体を含むメッセージ

      なお,MQDLH構造体を含むメッセージでは,最初のMQDLH構造体に続く構造体は省略できますが,MQDLH構造体の前にある構造体は省略できません。

    • MQヘッダ構造体は,二つ以上のセグメントに分割されてはなりません。つまり,構造体は一つのセグメントに含まれなければなりません。