MQGET-获取消息

MQGET 调用从使用 MQOPEN 调用打开的本地队列中检索消息。

语法

MQGETHconnHobjMsgDescGetMsgOptsBufferLengthBufferDataLengthCompCodeReason)

参数

Hconn
类型 :MQHCONN-输入

此句柄表示与队列管理器的连接。 先前的 MQCONN 或 MQCONNX 调用返回了 Hconn 的值。

z/OS® for CICS® 应用程序上,可以省略 MQCONN 调用,并为 Hconn 指定以下值:
MQHC_DEF_HCONN
缺省连接句柄。
Hobj
类型 :MQHOBJ-输入
此句柄表示要从中检索消息的队列。 Hobj 的值由先前的 MQOPEN 调用返回。 必须已使用以下一个或多个选项打开队列 (请参阅 MQOPEN-Open object 以获取详细信息):
  • MQOO_INPUT_SHARED
  • MQOO_INPUT_EXCLUSIVE
  • MQOO_INPUT_AS_Q_DEF
  • MQOO_BROWSE
MsgDesc
类型 :MQMD-输入/输出

此结构描述所需消息的属性以及检索的消息的属性。 请参阅 MQMD-消息描述符 以获取详细信息。

如果 BufferLength 小于消息长度,那么队列管理器将填充 MsgDesc ,无论是否在 GetMsgOpts 参数上指定 MQGMO_ACCEPT_TRUNCATED_MSG (请参阅 MQGMO-选项字段 )。

如果应用程序提供 version-1 MQMD ,那么返回的消息具有前缀为应用程序消息数据的 MQMDE ,但仅当 MQMDE 中的一个或多个字段具有非缺省值时。 如果 MQMDE 中的所有字段都具有缺省值,那么将省略 MQMDE。 MQMD 中的 格式 字段中的 MQFMT_MD_EXTENSION 格式名称指示存在 MQMDE。

如果在 MsgHandle 字段中提供了有效的消息句柄,那么应用程序不需要提供 MQMD 结构。 如果此字段中未提供任何内容,那么将从与消息句柄关联的描述符中获取消息描述符。

如果应用程序提供消息句柄而不是 MQMD 结构,并指定 MQGMO_PROPERTIES_FORCE_MQRFH2,那么调用将失败,原因码为 MQRC_MD_ERROR。 如果应用程序未提供 MQMD 结构并指定 MQGMO_PROPERTIES_AS_Q_DEF ,并且 PropertyControl 队列属性为 MQPROP_FORCE_MQRFH2,那么调用也将失败,原因码为 MQRC_MD_ERROR。

如果指定了匹配选项并且正在使用与消息句柄相关联的消息描述符,那么用于匹配的输入字段来自消息句柄。

GetMsgOpts
类型 :MQGMO-输入/输出

请参阅 MQGMO-Get-message 选项 以获取详细信息。

BufferLength
类型 :MQLONG-输入

这是 Buffer 区域的长度 (以字节计)。 为没有数据的消息指定零,或者如果要从队列中除去消息并废弃数据 (在这种情况下,必须指定 MQGMO_ACCEPT_TRUNCATED_MSG)。

注: 可以从队列读取的最长消息的长度由 MaxMsgLength 队列属性提供; 请参阅 队列属性
缓冲区
类型:MQBYTExBufferLength- 输出

这是用于包含消息数据的区域。 将缓冲区与消息中数据的性质相应的边界对齐。 4 字节对齐适用于大多数消息 (包括包含 IBM® MQ 头结构的消息) ,但某些消息可能需要更严格的对齐。 例如,包含 64 位二进制整数的消息可能需要 8 字节对齐。

如果 BufferLength 小于消息长度,那么会将尽可能多的消息移动到 Buffer中。 如果在 GetMsgOpts 参数上指定了 MQGMO_ACCEPT_TRUNCATED_MSG ,那么会发生此情况 (请参阅 MQGMO-选项字段 以获取更多信息)。

Buffer 中数据的字符集和编码由 MsgDesc 参数中返回的 CodedCharSetIdEncoding 字段提供。 如果这些值与接收方所需的值不同,那么接收方必须将应用程序消息数据转换为所需的字符集和编码。 可以使用 MQGMO_CONVERT 选项 (必要时带有用户编写的出口) 来转换消息数据; 请参阅 MQGMO-Get-message 选项 以获取此选项的详细信息。

注: MQGET 调用上的所有其他参数都采用本地队列管理器的字符集和编码 (由 CodedCharSetId 队列管理器属性和 MQENC_NATIVE 提供)。

如果调用失败,那么缓冲区的内容可能仍已更改。

在 C 编程语言中,参数被声明为一个指向 void 的指针: 任何类型的数据的地址都可以被指定为参数。

如果 BufferLength 参数为零,那么不会引用 Buffer ; 在这种情况下,以 C 或 System/390 汇编程序编写的程序传递的参数地址可以为空。

DataLength
类型:MQLONG - 输出

这是应用程序数据 在消息中的长度 (以字节计)。 如果此值大于 BufferLength,那么在 Buffer 参数中仅返回 BufferLength 字节 (即,消息被截断)。 如果值为零,那么消息不包含任何应用程序数据。

如果 BufferLength 小于消息长度,那么 DataLength 仍由队列管理器完成,无论是否在 GetMsgOpts 参数上指定 MQGMO_ACCEPT_TRUNCATED_MSG (请参阅 MQGMO-选项字段 以获取更多信息)。 这允许应用程序确定容纳消息数据所需的缓冲区大小,然后使用适当大小的缓冲区重新发出调用。

但是,如果指定了 MQGMO_CONVERT 选项,并且转换后的消息数据太长,无法放入 Buffer中,那么针对 DataLength 返回的值为:
  • 队列管理器定义的格式的 未转换 数据的长度。

    在这种情况下,如果数据的性质导致其在转换期间扩展,那么应用程序必须为 DataLength分配大于队列管理器返回的值的缓冲区。

  • 数据转换出口针对应用程序定义的格式返回的值。
CompCode
类型:MQLONG - 输出
完成代码;此完成代码为以下其中一项:
MQCC_OK
成功完成。
MQCC_WARNING
警告(部分完成)。
MQCC_FAILED
调用失败。
原因
类型:MQLONG - 输出

列出的原因码是队列管理器可以针对 Reason 参数返回的原因码。 如果应用程序指定了 MQGMO_CONVERT 选项,并且调用了用户编写的出口来转换部分或所有消息数据,那么该出口将决定对 Reason 参数返回的值。 因此,记录的值以外的值是可能的。

如果 CompCode 为 MQCC_OK:
MQRC_NONE
(0, X'000') 没有要报告的原因。
如果 CompCode 为 MQCC_WARNING:
MQRC_CONVERTED_MSG_TOO_BIG
(2120 , X'848 ') 转换的数据对于缓冲区太大。
MQRC_CONVERTED_STRING_TOO_BIG
(2190,X'88E')转换后的字符串对于字段来说太大。
MQRC_DBCS_ERROR
(2150 , X'866 ') DBCS 字符串无效。
MQRC_FORMAT_ERROR
(2110,X'83E')报文格式无效。
MQRC_INCOMPLETE_GROUP
(2241,X'8C1')报文组未完成。
MQRC_INCOMPLETE_MSG
(2242,X'8C2')逻辑报文未完成。
MQRC_INCONSISTENT_CCSIDS
(2243,X'8C3')报文段的 CCSID 不同。
MQRC_INCONSISTENT_ENCODINGS
(2244,X'8C4')报文段的编码不同。
MQRC_INCONSISTENT_UOW
(2245,X'8C5')工作单位规格不一致。
MQRC_MSG_TOKEN_ERROR
(2331,X'91B')信息标记使用无效。
MQRC_NO_MSG_LOCKED
(2209,X'8A1')未锁定报文。
MQRC_NOT_汇率
(2119 , X'847 ') 未转换消息数据。
MQRC_OPTIONS_CHANGED
(nnnn , X'xxx ') 已更改需要一致的选项。
MQRC_PARTIALLY_汇率
(2272,X'8E0')报文数据已部分转换。
MQRC_SIGNAL_REQUEST_接受
(2070 , X'816 ') 未返回消息 (但接受信号请求)。
MQRC_SOURCE_BUFFER_ERROR
(2145 , X'861 ') 源缓冲区参数无效。
MQRC_SOURCE_CCSID_ERROR
(2111,X'83F')源编码字符集标识符无效。
MQRC_SOURCE_DECIMAL_ENC_ERROR
(2113 , X'841 ') 无法识别消息中的压缩十进制编码。
MQRC_SOURCE_FLOAT_ENC_ERROR
(2114 , X'842 ') 无法识别消息中的浮点编码。
MQRC_SOURCE_INTEGER_ENC_ERROR
(2112 , X'840 ') 无法识别源整数编码。
MQRC_SOURCE_LENGTH_ERROR
(2143,X'85F')源长度参数无效。
MQRC_TARGET_BUFFER_ERROR
(2146 , X'862 ') 目标缓冲区参数无效。
MQRC_TARGET_CCSID_ERROR
(2115 , X'843 ') 目标编码字符集标识无效。
MQRC_TARGET_DECIMAL_ENC_ERROR
(2117 , X'845 ') 接收器指定的压缩十进制编码无法识别。
MQRC_TARGET_FLOAT_ENC_ERROR
(2118 , X'846 ') 接收器指定的浮点编码无法识别。
MQRC_TARGET_INTEGER_ENC_ERROR
(2116 , X'844 ') 无法识别目标整数编码。
MQRC_TRUNCATED_MSG_RECEIVED
(2079,X'81F')已返回截断报文(处理已完成)。
MQRC_TRUNCATED_MSG_FAILED
(2080 , X'820 ') 已返回截断的消息 (处理未完成)。
如果 CompCode 是 MQCC_FAILED:
MQRC_ADAPTER_NOT_AVAILABLE
(2204, X'89C') 适配器不可用。
MQRC_ADAPTER_CONV_LOAD_ERROR
(2133 , X'855 ') 无法装入数据转换服务模块。
MQRC_ADAPTER_SERV_LOAD_ERROR
(2130, X'852') 无法装入适配器服务模块。
MQRC_API_EXIT_ERROR
(2374, X'946') API 出口失败。
MQRC_API_EXIT_LOAD_ERROR
(2183 , X'887 ') 无法装入 API 出口。
MQRC_ASID_MISMATCH
(2157, X'86D') 主 ASID (Primary ASID) 与主 ASID (home ASID) 不同。
MQRC_BACKED_OUT
(2003,X'7D3')工作单位退出。
MQRC_BUFFER_ERROR
(2004,X'7D4')缓冲区参数无效。
MQRC_BUFFER_LENGTH_ERROR
(2005, X'7D5') 缓冲区长度参数无效。
MQRC_CALL_IN_PROGRESS
(2219, X'8AB') 在先前调用完成前输入了 MQI 调用。
MQRC_CF_NOT_AVAILABLE
(2345 , X' 929 ') 耦合设施不可用。
MQRC_CF_STRUC_FAILED
(2373 , X' 945 ') 耦合设施结构失败。
MQRC_CF_STRUC_IN_USE
(2346,X'92A')使用中的耦合设施结构。
MQRC_CF_STRUC_LIST_HDR_IN_USE
(2347,X'92B')正在使用耦合-设施结构列表头。
MQRC_CICS_WAIT_FAILED
(2140,X'85C') 等待请求被 "CICS拒绝 .
MQRC_CONNECTION_BROKEN
(2009, X'7D9') 与队列管理器的连接丢失。
MQRC_CONNECTION_NOT_AUTHORIZED
(2217,X'8A9')未授权连接。
MQRC_CONNECTION_QUIESCING
(2202, X'89A') 连接正在停顿。
MQRC_CONNECTION_STOPPING
(2203, X'89B') 连接正在关闭。
MQRC_CORREL_ID_ERROR
(2207,X'89F')相关标识符错误。
MQRC_DATA_LENGTH_ERROR
(2010,X'7DA')数据长度参数无效。
MQRC_DB2_NOT_AVAILABLE
(2342 , X' 926 ') Db2® 子系统不可用。
MQRC_GET_禁止
(2016,X'7E0')获得队列抑制。
MQRC_GLOBAL_UOW_CONFLICT
(2351,X'92F')全球工作单位冲突。
MQRC_GMO_ERROR
(2186,X'88A') Get-message 选项结构无效。
MQRC_HANDLE_IN_USE_FOR_UOW
(2353 , X' 931 ') 用于全局工作单元的句柄。
MQRC_HCONN_ERROR
(2018, X'7E2') 连接句柄无效。
MQRC_HOBJ_ERROR
(2019,X'7E3')对象句柄无效。
MQRC_INCONSISTENT_BROWSE
(2259,X'8D3')不符合浏览规范。
MQRC_INCONSISTENT_UOW
(2245,X'8C5')工作单位规格不一致。
MQRC_INVALID_MSG_UNDER_CURSOR
(2246,X'8C6')光标下的信息无效,无法检索。
MQRC_LOCAL_UOW_CONFLICT
(2352 , X' 930 ') 全局工作单元与本地工作单元冲突。
MQRC_MATCH_OPTIONS_ERROR
(2247,X'8C7')匹配选项无效。
MQRC_MD_ERROR
(2026,X'7EA')报文描述符无效。
MQRC_MSG_ID_ERROR
(2206,X'89E') 信息标识符错误。
MQRC_MSG_SEQ_NUMBER_ERROR
(2250,X'8CA')报文序列号无效。
MQRC_MSG_TOKEN_ERROR
(2331,X'91B')信息令牌使用无效。
MQRC_NO_MSG_AVAILABLE
(2033,X'7F1')无信息。
MQRC_NO_MSG_UNDER_CURSOR
(2034,X'7F2') 浏览光标未定位在信息上。
MQRC_NOT_OPEN_FOR_BROWSE
(2036,X'7F4')队列未开放浏览。
MQRC_NOT_OPEN_FOR_INPUT
(2037,X'7F5')队列未开放输入。
MQRC_OBJECT_CHANGED
(2041,X'7F9')打开后对象定义已更改。
MQRC_OBJECT_DAMAGED
(2101 , X'835 ') 对象已损坏。
MQRC_OPTIONS_ERROR
(2046,X'7FE') 选项无效或不一致。
MQRC_PAGESET_ERROR
(2193 , X'891 ') 访问页集数据集时出错。
MQRC_Q_DELETED
(2052 , X'804 ') 队列已删除。
MQRC_Q_INDEX_TYPE_ERROR
(2394,X'95A')队列的索引类型错误。
MQRC_Q_MGR_NAME_ERROR
(2058, X'80A') 队列管理器名称无效或者未知。
MQRC_Q_MGR_NOT_AVAILABLE
(2059, X'80B') 队列管理器针对连接不可用。
MQRC_Q_MGR_QUIESCING
(2161, X'871') 队列管理器正在停顿。
MQRC_Q_MGR_STOPPING
(2162, X'872') 队列管理器正在关闭。
MQRC_RESOURCE_PROBLEM
(2102, X'836') 没有足够系统资源可用。
MQRC_SECOND_MARK_NOT_ALLOWED
(2062,X'80E') 一条信息已被标记。
MQRC_SIGNAL_众数
(2069 , X'815 ') 此句柄的信号未完成。
MQRC_SIGNAL1_ERROR
(2099 , X'833 ') 信号字段无效。
MQRC_STORAGE_MEDIUM_FULL
(2192 , X'890 ') 外部存储介质已满。
MQRC_STORAGE_NOT_AVAILABLE
(2071, X'817') 没有足够的存储空间可用。
MQRC_SUPPRESSED_BY_EXIT
(2109,X'83D')退出程序抑制了调用。
MQRC_SYNCPOINT_LIMIT_已达到
(2024,X'7E8')当前工作单元内无法处理更多信息。
MQRC_SYNCPOINT_NOT_AVAILABLE
(2072 , X'818 ') 同步点支持不可用。
MQRC_UNEXPECTED_ERROR
(2195, X'893') 发生了意外错误。
MQRC_UOW_ENLISTMENT_ERROR
(2354 , X' 932 ') 在全局工作单元中登记失败。
MQRC_UOW_MIX_NOT_SUPPORTED
(2355 , X' 933 ') 不支持混合工作单元调用。
MQRC_UOW_NOT_AVAILABLE
(2255,X'8CF')队列管理器无法使用的工作单位。
MQRC_WAIT_INTERVAL_ERROR
(2090,X'82A') MQGMO 中的等待时间间隔无效。
MQRC_不法 _gmo_version
(2256,X'8D0')提供的 MQGMO 版本错误。
MQRC_不法 _md_version
(2257,X'8D1')提供的 MQMD 版本错误。

有关这些代码的详细信息,请参阅 消息和原因码

使用说明

  1. 通常会从队列中删除检索到的消息。 此删除可作为 MQGET 调用本身的一部分进行,也可作为同步点的一部分进行。

    浏览选项包括 :MQGMO_BROWSE_FIRST , MQGMO_BROWSE_NEXT 和 MQGMO_BROWSE_MSG_UNDER_CURSOR。

  2. 如果使用其中一个浏览选项指定了 MQGMO_LOCK 选项,那么将锁定已浏览的消息,以使其仅对此句柄可见。

    如果指定了 MQGMO_UNLOCK 选项,那么将解锁先前锁定的消息。 在此情况下,不会检索任何消息,并且不会检查或变更 MsgDescBufferLengthBufferDataLength 参数。

  3. 对于发出 MQGET 调用的应用程序,如果应用程序异常终止或在处理调用时断开连接,那么检索到的消息可能会丢失。 出现此问题的原因是,在代表应用程序发出 MQGET 调用的队列管理器所在的平台上运行的代理程序无法检测应用程序丢失,直到代理程序将消息从队列中除去之后才会将消息返回到应用程序。 持久消息和非持久消息都可能发生此问题。

    要消除以这种方式丢失消息的风险,请始终在工作单元中检索消息。 即,通过在 MQGET 调用上指定 MQGMO_SYNCPOINT 选项,并在消息处理完成时使用 MQCMIT 或 MQBACK 调用落实或回退工作单元。 如果指定了 MQGMO_SYNCPOINT ,并且客户机异常终止或连接已断开,那么代理将回退队列管理器上的工作单元,并在队列上恢复消息。 有关同步点的更多信息,请参阅 IBM MQ 应用程序中的同步点注意事项

    对于 IBM MQ 客户机以及与队列管理器在同一平台上运行的应用程序,可能会出现此情况。

  4. 如果应用程序将消息序列放在单个工作单元中的特定队列上,然后成功落实该工作单元,那么这些消息可供检索,如下所示:
    • 如果队列是 非共享队列 (即本地队列) ,那么工作单元中的所有消息将同时可用。
    • 如果队列是 共享队列,那么工作单元中的消息将按其放入的顺序变为可用,但不会同时显示所有消息。 当系统大量负载时,可能会成功检索工作单元中的第一条消息,但对于工作单元中的第二条消息或后续消息的 MQGET 调用可能会失败,并返回 MQRC_NO_MSG_AVAILABLE。 如果发生此问题,那么应用程序必须稍等片刻,然后重试该操作。
  5. 如果应用程序在不使用消息组的情况下将消息序列放在同一队列上,那么在满足特定条件时将保留这些消息的顺序。 请参阅 MQPUT 使用说明 以获取详细信息。 如果满足条件,那么将按照发送消息的顺序向接收应用程序显示消息,前提是:
    • 只有一个接收方从队列中获取消息。

      如果有两个或多个应用程序从队列中获取消息,那么它们必须与发送方同意用于标识属于序列的消息的机制。 例如,发送方可以将序列中的消息中的所有 CorrelId 字段设置为该消息序列唯一的值。

    • 接收方不会故意更改检索顺序,例如通过指定特定 MsgIdCorrelId
    如果发送应用程序将消息作为消息组放置,那么如果接收应用程序在 MQGET 调用上指定了 MQGMO_LOGICAL_ORDER 选项,那么消息将以正确顺序呈现给接收应用程序。 有关消息组的更多信息,请参阅:

    如果用户正在同步点下的组中获取消息,那么他们必须确保在尝试完成事务之前处理完整组。

  6. 应用程序必须在 MsgDesc 参数的 Feedback 字段中测试反馈代码 MQFB_QUIT ,如果它们找到此值,那么结束。 请参阅 MQMD-反馈字段 以获取更多信息。
  7. 如果 Hobj 标识的队列是使用 MQOO_SAVE_ALL_CONTEXT 选项打开的,并且来自 MQGET 调用的完成代码是 MQCC_OK 或 MQCC_WARNING ,那么与队列句柄 Hobj 关联的上下文将设置为已检索的消息的上下文 (除非设置了 MQGMO_BROWSE_FIRST , MQGMO_BROWSE_NEXT 或 MQGMO_BROWSE_MSG_UNDER_CURSOR 选项,在这种情况下,上下文将标记为不可用)。

    您可以通过指定 MQPMO_PASS_IDENTITY_CONTEXT 或 MQPMO_PASS_ALL_CONTEXT 选项,在后续 MQPUT 或 MQPUT1 调用上使用已保存的上下文。 这使接收到的消息的上下文能够全部或部分传输到另一个消息 (例如,当消息被转发到另一个队列时)。 有关消息上下文的更多信息,请参阅 消息上下文

  8. 如果在 GetMsgOpts 参数中包含 MQGMO_CONVERT 选项,那么在将数据放入 Buffer 参数之前,会将应用程序消息数据转换为接收应用程序所请求的表示:
    • 消息中的控制信息中的 Format 字段标识应用程序数据的结构,而消息中的控制信息中的 CodedCharSetIdEncoding 字段指定其字符集标识和编码。
    • 发出 MQGET 调用的应用程序在 MsgDesc 参数的 CodedCharSetIdEncoding 字段中指定要将应用程序消息数据转换为的字符集标识和编码。
    当需要转换消息数据时,根据消息中的控制信息中 Format 字段的值,由队列管理器本身或用户编写的出口执行转换:
    • 以下格式名称是由队列管理器转换的格式; 这些格式称为 "内置" 格式:
      • MQFMT_ADMIN
      • MQFMT_CICS (仅限 z/OS )
      • MQFMT_COMMAND_1
      • MQFMT_COMMAND_2
      • MQFMT_DEAD_LETTER_HEADER
      • MQFMT_DIST_HEADER
      • MQFMT_EVENT V 1
      • MQFMT_EVENT V 2 (仅限 z/OS )
      • MQFMT_IMS
      • MQFMT_IMS_VAR_STRING
      • MQFMT_MD_EXTENSION
      • MQFMT_PCF
      • MQFMT_REF_MSG_HEADER
      • MQFMT_RF_HEADER
      • MQFMT_RF_HEADER_2
      • MQFMT_STRING
      • MQFMT_TRIGGER
      • MQFMT_WORK_INFO_HEADER (仅限 z/OS )
      • MQFMT_XMIT_Q_HEADER
    • 格式名 MQFMT_NONE 是一个特殊值,指示未定义消息中数据的性质。 因此,从队列中检索消息时,队列管理器不会尝试转换。
      注: 如果在 MQGET 调用上为格式名为 MQFMT_NONE 的消息指定了 MQGMO_CONVERT ,并且该消息的字符集或编码与 MsgDesc 参数中指定的字符集或编码不同,那么将在 Buffer 参数中返回该消息 (假定没有其他错误) ,但该调用将完成并返回完成代码 MQCC_WARNING 和原因码 MQRC_FORMAT_ERROR。

      当消息数据的性质意味着不需要转换时,或者当发送和接收应用程序之间已同意发送消息数据的格式时,可以使用 MQFMT_NONE。

    • 所有其他格式名称将消息传递到用户编写的出口以进行转换。 除特定于环境的添加外,出口具有与格式相同的名称。 用户指定的格式名称不得以字母 IBM MQ开头。

      有关数据转换出口的详细信息,请参阅 数据转换出口

    可以在任何受支持的字符集和编码之间转换消息中的用户数据。 但是,请注意,如果消息包含一个或多个 IBM MQ 头结构,那么对于队列名称中有效的任何字符,无法将消息转换为具有双字节或多字节字符的字符集。 如果尝试了 MQRC_SOURCE_CCSID_ERROR 或 MQRC_TARGET_CCSID_ERROR ,那么会生成原因码 MQRC_SOURCE_CCSID_ERROR 或 MQRC_TARGET_CCSID_ERROR ,并且返回未转换的消息。 Unicode 字符集 UTF-16 是此类字符集的示例。

    从 MQGET 返回时,以下原因码指示消息已成功转换:
    • MQRC_NONE
    以下原因码指示消息可能已成功转换; 应用程序必须检查 MsgDesc 参数中的 CodedCharSetIdEncoding 字段以找出:
    • MQRC_TRUNCATED_MSG_RECEIVED
    所有其他原因码都指示未转换消息。
    注: 仅当此出口符合 数据转换出口中描述的处理准则时,此原因码的解释才适用于用户编写的出口执行的转换。
  9. 使用面向对象的接口获取消息时,可以选择不指定缓冲区来保存 MQGET 调用的消息数据。 但是,在 IBM MQ的版本中,在 IBM WebSphere® MQ 7.0之前的版本中, MQGET 可能会失败,原因码为 MQRC_CONVERTED_MSG_TO_BIG ,即使未指定缓冲区也是如此。 从 IBM WebSphere MQ 7.0开始,当您在不限制接收消息缓冲区大小的情况下使用面向对象的应用程序获取消息时,应用程序不会因 MQRC_CONVERTED_MSG_TOO_BIG 而失败,并接收转换后的消息。 对于以下环境,情况如此:
    • .NET,包括完全受管的应用程序
    • C++
    • Java ( IBM MQ classes for Java )
    注: 对于所有客户机,如果 sharingConversations 的值为零,那么通道将像在 IBM WebSphere MQ 7.0之前一样运行,并且消息处理将还原为 IBM WebSphere MQ 6 行为。 在此情况下,如果缓冲区太小而无法接收转换后的消息,那么将返回未转换的消息,原因码为 MQRC_CONVERTED_MSG_TOO_BIG。 有关 sharingConversations的更多信息,请参阅 在客户机应用程序中使用共享对话
  10. 对于内置格式,当指定 MQGMO_CONVERT 选项时,队列管理器可以执行消息中字符串的 缺省转换 。 缺省转换允许队列管理器在转换字符串数据时使用近似于实际字符集的安装指定的缺省字符集。 因此, MQGET 调用可以使用完成代码 MQCC_OK 成功,而不是使用 MQCC_WARNING 和原因码 MQRC_SOURCE_CCSID_ERROR 或 MQRC_TARGET_CCSID_ERROR 完成。
    注: 使用近似字符集来转换字符串数据的结果是某些字符可能转换不正确。 要避免这种情况,请在字符串中使用对实际字符集和缺省字符集都通用的字符。
    缺省转换适用于应用程序消息数据以及 MQMD 和 MQMDE 结构中的字符字段:
    • 仅当下列所有语句都为 true 时,才会进行应用程序消息数据的缺省转换:
      • 应用程序指定 MQGMO_CONVERT。
      • 该消息包含必须从不支持的字符集转换或转换为不支持的字符集的数据。
      • 安装或重新启动队列管理器时启用了缺省转换。
    • 如果为队列管理器启用了缺省转换,那么将根据需要对 MQMD 和 MQMDE 结构中的字符字段进行缺省转换。 即使 MQGET 调用上的应用程序未指定 MQGMO_CONVERT 选项,也会执行转换。
  11. 对于 Visual Basic 编程语言,以下要点适用:
    • 如果 Buffer 参数的大小小于 BufferLength 参数指定的长度,那么调用将失败,原因码为 MQRC_STORAGE_NOT_AVAILABLE。
    • Buffer 参数声明为类型为 String。 如果要从队列中检索的数据不是 String类型,请使用 MQGETAny 调用来代替 MQGET。

      MQGETAny 调用具有与 MQGET 调用相同的参数,但 Buffer 参数声明为 Any类型,允许检索任何类型的数据。 但是,这意味着无法检查 Buffer 以确保其大小至少为 BufferLength 字节。

  12. 当启用预读时,并非所有 MQGET 选项都受支持。 下表指示允许哪些选项以及是否可以在 MQGET 调用之间更改这些选项。
    表 1. 启用预读时允许的 MQGET 选项
      在启用预读并且可以在 MQGET 调用之间进行更改时允许 在启用预读但无法在 MQGET 调用之间更改时允许 a 启用预读时不允许的 MQGET 选项 b
    MQGET MD 值
    MsgId c
    CorrelId c
    编码
    ""CodedCharSetId""
    MQGET MQGMO 选项
    MQGMO_WAIT
    MQGMO_NO_WAIT
    MQGMO_FAIL_IF_QUIESCING
    MQGMO_BROWSE_FIRST d
    MQGMO_BROWSE_NEXT d
    MQGMO_BROWSE_MESSAGE
    _UNDER_CURSOR d

    MQGMO_SYNCPOINT_IF_PERSISTENT
    MQGMO_NO_SYNCPOINT
    MQGMO_ACCEPT_TRUNCATED_MSG
    MQGMO_CONVERT
    MQGMO_LOGICAL_ORDER
    MQGMO_COMPLETE_MSG
    MQGMO_ALL_MSGS_AVAILABLE
    MQGMO_ALL_SEGMENTS_AVAILABLE
    MQGMO_MARK_BROWSE_HANDLE
    MQGMO_MARK_BROWSE_CO_OP
    MQGMO_UNMARK_BROWSE_CO_OP
    MQGMO_UNMARK_BROWSE_HANDLE
    MQGMO_UNMARKED_BROWSE_MSG
    MQGMO_PROPERTIES_FORCE_MQRFH2
    MQGMO_NO_PROPERTIES
    MQGMO_PROPERTIES_IN_HANDLE
    MQGMO_PROPERTIES_COMPATIBILITY

    MQGMO_SET_SIGNAL
    MQGMO_SYNCPOINT
    MQGMO_MARK_SKIP
    _BACKOUT
    MQGMO_MSG_UNDER
    _CURSOR d
    MQGMO_LOCK
    MQGMO_UNLOCK

    MQGMO 值   MsgHandle  
    1. 如果在 MQGET 调用之间更改了这些选项,那么将返回 MQRC_OPTIONS_CHANGED 原因码。
    2. 如果在第一个 MQGET 调用上指定这些选项,那么将禁用预读。 如果在后续 MQGET 调用上指定这些选项,那么将返回原因码 MQRC_OPTIONS_ERROR。
    3. 客户机应用程序需要意识到,如果 MsgId 和 CorrelId 值在 MQGET 调用之间发生更改,那么具有先前值的消息可能已发送至客户机,并保留在客户机预读缓冲区中,直至被使用(或自动清除)为止。
    4. 第一个 MQGET 调用确定在启用了预读时是否要从队列中浏览或获取消息。 如果应用程序尝试同时执行浏览与获取操作,将返回原因码 MQRC_OPTIONS_CHANGED。
    5. MQGMO_MSG_UNDER_CURSOR 不能与预读配合使用。 在启用了预读时,可浏览或获取消息,但是不能同时执行这两个操作。
  13. 仅当将未落实的消息放入与 get 相同的本地工作单元时,应用程序才能以破坏性方式获取未落实的消息。 应用程序无法以非破坏性方式获取未落实的消息。
  14. 可以在工作单元中检索浏览光标下的消息。 无法以此方式检索未落实的消息。

C 调用

MQGET (Hconn, Hobj, &MsgDesc, &GetMsgOpts, BufferLength, Buffer,
      &DataLength, &CompCode, &Reason);
按如下所示声明参数:
MQHCONN  Hconn;         /* Connection handle */
MQHOBJ   Hobj;          /* Object handle */
MQMD     MsgDesc;       /* Message descriptor */
MQGMO    GetMsgOpts;    /* Options that control the action of MQGET */
MQLONG   BufferLength;  /* Length in bytes of the Buffer area */
MQBYTE   Buffer[n];     /* Area to contain the message data */
MQLONG   DataLength;    /* Length of the message */
MQLONG   CompCode;      /* Completion code */
MQLONG   Reason;        /* Reason code qualifying CompCode */

COBOL 调用

CALL 'MQGET' USING HCONN, HOBJ, MSGDESC, GETMSGOPTS, BUFFERLENGTH,
BUFFER, DATALENGTH, COMPCODE, REASON.
按如下所示声明参数:
**   Connection handle
 01  HCONN         PIC S9(9) BINARY.
**   Object handle
 01  HOBJ          PIC S9(9) BINARY.
**   Message descriptor
 01  MSGDESC.
     COPY CMQMDV.
**   Options that control the action of MQGET
 01  GETMSGOPTS.
     COPY CMQGMOV.
**   Length in bytes of the BUFFER area
 01  BUFFERLENGTH  PIC S9(9) BINARY.
**   Area to contain the message data
 01  BUFFER        PIC X(n).
**   Length of the message
 01  DATALENGTH    PIC S9(9) BINARY.
**   Completion code
 01  COMPCODE      PIC S9(9) BINARY.
**   Reason code qualifying COMPCODE
 01  REASON        PIC S9(9) BINARY.

PL/I 调用

call MQGET (Hconn, Hobj, MsgDesc, GetMsgOpts, BufferLength, Buffer,
           DataLength, CompCode, Reason);
按如下所示声明参数:
dcl Hconn         fixed bin(31);  /* Connection handle */
dcl Hobj          fixed bin(31);  /* Object handle */
dcl MsgDesc       like MQMD;      /* Message descriptor */
dcl GetMsgOpts    like MQGMO;     /* Options that control the action of
                                     MQGET */
dcl BufferLength  fixed bin(31);  /* Length in bytes of the Buffer
                                     area */
dcl Buffer        char(n);        /* Area to contain the message data */
dcl DataLength    fixed bin(31);  /* Length of the message */
dcl CompCode      fixed bin(31);  /* Completion code */
dcl Reason        fixed bin(31);  /* Reason code qualifying CompCode */

高级汇编程序调用

         CALL MQGET,(HCONN,HOBJ,MSGDESC,GETMSGOPTS,BUFFERLENGTH,       
               BUFFER,DATALENGTH,COMPCODE,REASON)
按如下所示声明参数:
HCONN         DS       F      Connection handle
HOBJ          DS       F      Object handle
MSGDESC       CMQMDA   ,      Message descriptor
GETMSGOPTS    CMQGMOA  ,      Options that control the action of MQGET
BUFFERLENGTH  DS       F      Length in bytes of the BUFFER area
BUFFER        DS       CL(n)  Area to contain the message data
DATALENGTH    DS       F      Length of the message
COMPCODE      DS       F      Completion code
REASON        DS       F      Reason code qualifying COMPCODE

Visual Basic 调用

MQGET Hconn, Hobj, MsgDesc, GetMsgOpts, BufferLength, Buffer,
DataLength, CompCode, Reason
按如下所示声明参数:
Dim Hconn        As Long   'Connection handle'
Dim Hobj         As Long   'Object handle'
Dim MsgDesc      As MQMD   'Message descriptor'
Dim GetMsgOpts   As MQGMO  'Options that control the action of MQGET'
Dim BufferLength As Long   'Length in bytes of the Buffer area'
Dim Buffer       As String 'Area to contain the message data'
Dim DataLength   As Long   'Length of the message'
Dim CompCode     As Long   'Completion code'
Dim Reason       As Long   'Reason code qualifying CompCode'