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の上限は状況によって異なります。

● 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

完了コードです。

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

● Reason(MQLONG型) -output

理由コードです。

CompCode引数がMQCC_OKの場合

理由コード数値意味
MQRC_NONE0理由コードはありません。

CompCode引数がMQCC_WARNINGの場合

理由コード数値意味
MQRC_INCOMPLETE_GROUP2241メッセージグループが完全ではありません。
MQRC_INCOMPLETE_MSG2242論理メッセージが完全ではありません。
MQRC_INCONSISTENT_PERSISTENCE2185永続性指定が矛盾しています。
MQRC_INCONSISTENT_UOW2245コミット単位の指定が矛盾しています。
MQRC_MULTIPLE_REASONS2136複数の理由コードが返されました。
MQRC_PRIORITY_EXCEEDS_MAXIMUM2049メッセージ優先度が最大値を超えています。
MQRC_UNKNOWN_REPORT_OPTION2104メッセージ記述子中の報告オプションを認識できません。

CompCode引数がMQCC_FAILEDの場合

理由コード数値意味
MQRC_BUFFER_ERROR2004バッファの引数が不正です。
MQRC_BUFFER_LENGTH_ERROR2005バッファ長の引数が不正です。
MQRC_CLUSTER_RESOLUTION_ERROR2189クラスタ名称の解決に失敗しました。
MQRC_CLUSTER_RESOURCE_ERROR2269クラスタリソースのエラーです。
MQRC_CONTEXT_HANDLE_ERROR2097参照先のキューハンドルにコンテキストが保存されていません。
MQRC_CONTEXT_NOT_AVAILABLE2098参照先のキューハンドルのコンテキストが不正です。
MQRC_DH_ERROR2135配布リストの構造体が不正です。
MQRC_EXPIRY_ERROR2013メッセージ保持時間が不正です。
MQRC_FEEDBACK_ERROR2014報告メッセージ返答コードが不正です。
MQRC_HCONN_ERROR2018コネクションハンドルが不正です。
MQRC_HOBJ_ERROR2019オブジェクトハンドルが不正です。
MQRC_INCOMPLETE_GROUP2241メッセージグループが完全ではありません。
MQRC_INCOMPLETE_MSG2242論理メッセージが完全ではありません。
MQRC_INCONSISTENT_PERSISTENCE2185永続性指定が矛盾しています。
MQRC_INCONSISTENT_UOW2245コミット単位の指定が矛盾しています。
MQRC_MD_ERROR2026メッセージ記述子が不正です。
MQRC_MDE_ERROR2248メッセージ記述子の拡張子が不正です。
MQRC_MISSING_REPLY_TO_Q2027応答キューがありません。
MQRC_MSG_FLAGS_ERROR2249メッセージフラグが不正です。
MQRC_MSG_SEQ_NUMBER_ERROR2250メッセージシーケンス番号が不正です。
MQRC_MSG_TOO_BIG_FOR_Q2030メッセージ長がキューに定義された最大値を超えています。
MQRC_MSG_TYPE_ERROR2029メッセージ記述子中のメッセージタイプが不正です。
MQRC_MULTIPLE_REASONS2136複数の理由コードが返されています。
MQRC_NO_DESTINATIONS_AVAILABLE2270利用可能なあて先キューが存在しません。
MQRC_NOT_OPEN_FOR_OUTPUT2039キューが登録用にオープンされていません。
MQRC_NOT_OPEN_FOR_PASS_ALL2093キューが全コンテキスト引き渡し用にオープンされていません。
MQRC_NOT_OPEN_FOR_PASS_IDENT2094キューが識別コンテキスト引き渡し用にオープンされていません。
MQRC_NOT_OPEN_FOR_SET_ALL2095キューが全コンテキスト設定用にオープンされていません。
MQRC_NOT_OPEN_FOR_SET_IDENT2096キューが識別コンテキスト設定用にオープンされていません。
MQRC_OBJECT_DAMAGED2101オブジェクトが破損しています。
MQRC_OFFSET_ERROR2251メッセージセグメントのオフセットが不正です。
MQRC_OPEN_FAILED2137キューのオープンに失敗しました。
MQRC_OPTIONS_ERROR2046オプションが不正です。または,指定されていません。
MQRC_ORIGINAL_LENGTH_ERROR2252元のメッセージの長さが不正です。
MQRC_PCF_ERROR2149PCF構造体が不正です。
MQRC_PERSISTENCE_ERROR2047メッセージ永続性が不正です。
MQRC_PERSISTENT_NOT_ALLOWED2048キューは永続メッセージをサポートしていません。
MQRC_PMO_ERROR2173メッセージ登録オプションの構造体が不正です。
MQRC_PMO_RECORD_FLAGS_ERROR2158メッセージ登録レコードのフラグが不正です
MQRC_PRIORITY_ERROR2050メッセージ優先度が不正です。
MQRC_PUT_INHIBITED2051指定されたキューへの登録は禁止されています。
MQRC_PUT_MSG_RECORDS_ERROR2159メッセージ登録レコードが不正です。
MQRC_Q_DELETED2052キューが削除されています。
MQRC_Q_FULL2053キューが満杯です。
MQRC_Q_SPACE_NOT_AVAILABLE2056キューに対応するディスクに空き領域がありません。
MQRC_RECS_PRESENT_ERROR2154不正なレコードが存在します。
MQRC_REPORT_OPTIONS_ERROR2061メッセージ記述子中の報告オプションが不正です。
MQRC_RESOURCE_PROBLEM2102システム資源が不足しています。
MQRC_RESPONSE_RECORDS_ERROR2156応答レコードが不正です。
MQRC_SEGMENT_LENGTH_ZERO2253メッセージセグメント長が0です。
MQRC_STORAGE_NOT_AVAILABLE2071記憶容量が不足しています。
MQRC_SYNCPOINT_NOT_AVAILABLE2072同期点処理はできません。
MQRC_UNEXPECTED_ERROR2195予期しないエラーが発生しました。
MQRC_UOW_NOT_AVAILABLE2255コミット単位ではキューマネジャを使用できません。
MQRC_WRONG_MD_VERSION2257MQMD構造体で指定されたバージョンが誤っています。

詳細は,「付録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ヘッダ構造体は,二つ以上のセグメントに分割されてはなりません。つまり,構造体は一つのセグメントに含まれなければなりません。