选项 (MQLONG)

MQGMO 选项控制 MQGET的操作。 可以指定零个或多个选项。 如果需要多个可选值:
  • 添加值 (请勿多次添加相同的常量) ,或者
  • 使用按位 OR 运算组合值 (如果编程语言支持位运算)。
将记录无效选项的组合; 所有其他组合都有效。
等待选项: 以下选项与等待消息到达队列相关:
MQGMO_WAIT
应用程序将等待合适的消息到达。 应用程序等待的最大时间在 WaitInterval 中指定。
重要信息: 如果有合适的消息立即可用,那么没有等待或延迟。

如果 MQGET 个请求被禁止,或者 MQGET 个请求在等待时被禁止,那么将取消等待。 无论队列上是否存在适当的消息,调用都将完成 MQCC_FAILED 和原因码 MQRC_GET_INHIBITED

可以将 MQGMO_WAIT MQGMO_BROWSE_FIRST MQGMO_BROWSE_NEXT 选项配合使用。

如果多个应用程序正在同一共享队列上等待,那么以下规则将选择在合适的消息到达时激活哪个应用程序:

表 1. 用于激活共享队列上的 MQGET 调用的规则。
正在等待激活的 MQGET 个调用数 结果
使用 BROWSE 选项 没有 BROWSE 选项 1
None 一个或多个 将激活一个不带 BROWSE 选项的 MQGET 调用。
一个或多个 None 将激活所有带有 BROWSE 选项的 MQGET 调用。
一个或多个 一个或多个 将激活一个不带 BROWSE 选项的 MQGET 调用。 使用 BROWSE 选项激活的 MQGET 调用数不可预测。
如果没有 BROWSE 选项的多个 MQGET 调用正在同一队列上等待,那么将仅激活一个调用。 队列管理器尝试按以下顺序优先处理正在等待的调用:
  1. 只能由特定消息 (例如,具有特定 MsgId 和/或 CorrelId 的消息) 满足的特定 get-wait 请求。
  2. 可由任何消息满足的常规 get-wait 请求。
注:
  • 在第一类中,没有为更具体的 get-wait 请求提供额外的优先级。 例如,同时指定 MsgId CorrelId 的请求。
  • 在任一类别中,都无法预测选择了哪个应用程序。 特别是,等待时间最长的应用程序不一定是所选的应用程序。
  • 操作系统的路径长度和优先级调度注意事项可能意味着操作系统优先级低于预期的等待应用程序检索消息。
  • 也可能发生以下情况: 未处于等待状态的应用程序会优先检索消息,而不是其中的消息。
z/OS®上,以下要点适用:
  • 如果您希望应用程序在等待消息到达时继续执行其他工作,请考虑改为使用信号选项 ( MQGMO_SET_SIGNAL )。 但是,信号选项是特定于环境的; 您要在不同环境之间移植的应用程序不得使用它。
  • 如果有多个 MQGET 调用在等待同一消息,同时使用等待选项和信号选项,那么将平等地考虑每个等待调用。 将 MQGMO_SET_SIGNAL MQGMO_WAIT 一起指定时发生错误。 将此选项与未完成信号的队列句柄一起指定也是一个错误。
  • 如果对 IndexType MQIT_MSG_TOKEN的队列指定 MQGMO_WAIT MQGMO_SET_SIGNAL ,那么不允许选择条件。 这表示:
    • 如果您正在使用 version-1 MQGMO,请在 MQGET 调用 MQMI_NONEMQCI_NONE上指定的 MQMD 中设置 MsgId CorrelId 字段。
    • 如果要使用 version-2 或更高版本 MQGMO,请将 MatchOptions 字段设置为 MQMO_NONE
  • 对于共享队列上的 MQGET 调用,该调用是浏览请求或组消息的破坏性获取,并且 MsgId CorrelId 都不匹配,您的信号 ECB 将在 200 毫秒后发布MQEC_MSG_到了。

    即使在使用 MQEC_WAIT_INTERVAL_EXPIRED 发布队列时,在等待时间间隔到期之前,合适的消息可能尚未到达队列中,也会发生此情况。 发布MQEC_MSG_已到达时,必须重新发出第二个 MQGET 调用以检索消息 (如果有)。

    此方法用于确保及时通知您消息到达,但在与非共享队列上的类似调用序列进行比较时,可能会显示为意外的处理开销。

如果与 MQGMO_BROWSE_MSG_UNDER_CURSOR MQGMO_MSG_UNDER_CURSOR 一起指定,那么将忽略 MQGMO_WAIT ; 不会产生任何错误。

MQGMO_NO_WAIT
如果没有合适的消息可用,那么应用程序不会等待。 MQGMO_NO_WAITMQGMO_WAIT相反。 定义 MQGMO_NO_WAIT 以帮助程序文档。 如果两者都未指定,那么它是缺省值。
MQGMO_SET_SIGNAL
将此选项与 Signal1Signal2 字段配合使用。 它允许应用程序在等待消息到达时继续执行其他工作。 它还允许 (如果合适的操作系统设施可用) 应用程序等待消息到达多个队列。
注: MQGMO_SET_SIGNAL 选项特定于环境; 请勿将其用于要移植的应用程序。
在两种情况下,调用以与未指定此选项相同的方式完成:
  1. 如果当前可用的消息满足消息描述符中指定的条件。
  2. 如果检测到参数错误或其他同步错误。

如果当前没有满足消息描述符中指定的条件的消息可用,那么控制权将返回到应用程序,而不会等待消息到达。 CompCodeReason 参数设置为 MQCC_WARNING MQRC_SIGNAL_REQUEST_ACCEPTED。 未设置消息描述符中的其他输出字段以及 MQGET 调用的输出参数。 当适当的信息稍后到达时,将通过发布 ECB 来传递该信号。

然后,调用者必须重新发出 MQGET 调用以检索消息。 应用程序可以使用操作系统提供的功能来等待此信号。

如果操作系统提供了多重等待机制,那么您可以使用它来等待消息到达多个队列中的任何一个队列。

如果指定了非零 WaitInterval ,那么将在等待时间间隔到期后传递信号。 队列管理器还可以取消等待,在这种情况下,将传递信号。

多个 MQGET 调用可以为同一消息设置信号。 应用程序的激活顺序与针对 MQGMO_WAIT描述的顺序相同。

如果多个 MQGET 调用正在等待同一消息,那么将平等地考虑每个正在等待的调用。 这些调用可以包含等待和信号选项的混合。

在某些情况下, MQGET 调用可以检索消息,并且可以传递来自同一消息到达的信号。 在传递信号时,必须准备应用程序以确保没有消息可用。

队列句柄不能有多个未完成的信号请求。

此选项对于下列任何选项都无效:
  • MQGMO_UNLOCK
  • MQGMO_WAIT

对于共享队列上的 MQGET 调用,该调用是浏览请求或组消息的破坏性获取,并且 MsgIdCorrelId 都不匹配,用户的信号 ECB 将在 200 毫秒后发布 MQEC_MSG_ARRIVED

即使在使用 MQEC_WAIT_INTERVAL_EXPIRED发布队列时,在等待时间间隔到期之前,合适的消息可能尚未到达队列中,也会发生此情况。 发布 MQEC_MSG_ARRIVED 时,必须重新发出另一个 MQGET 调用以检索消息 (如果有)。

此方法用于确保及时通知您消息到达,但在与非共享队列上的类似调用序列进行比较时,可能会显示为意外的处理开销。

当不经常添加消息时,这不是高效的消息检索方法。 要避免浏览案例的此开销,请在 MQGET 调用上指定 MsgId (如果未建立索引或由 MsgId建立索引) 或 CorrelId (如果由 CorrelId建立索引) 匹配。

此选项仅在 z/OS 上受支持。

MQGMO_FAIL_IF_QUIESCING
如果队列管理器处于停顿状态,那么强制 MQGET 调用失败。

z/OS上,如果连接 (对于 CICS®IMS 应用程序) 处于停顿状态,那么此选项还会强制 MQGET 调用失败。

如果此选项与 MQGMO_WAITMQGMO_SET_SIGNAL一起指定,并且在队列管理器进入停顿状态时等待或信号未完成:
  • 已取消等待,调用将返回完成代码 MQCC_FAILED ,原因码为 MQRC_Q_MGR_QUIESCINGMQRC_CONNECTION_QUIESCING
  • 使用特定于环境的信号完成代码取消信号。

    z/OS上,信号完成,事件完成代码为 MQEC_Q_MGR_QUIESCINGMQEC_CONNECTION_QUIESCING

如果未指定 MQGMO_FAIL_IF_QUIESCING ,并且队列管理器或连接进入停顿状态,那么不会取消等待或信号。
同步点选项: 以下选项与 MQGET 调用参与工作单元相关:
MQGMO_SYNCPOINT
请求是在正常工作单元协议中运行。 该消息被标记为对其他应用程序不可用,但仅当落实工作单元时才会从队列中删除该消息。 如果回退工作单元,那么该消息将再次可用。

您可以使 MQGMO_SYNCPOINTMQGMO_NO_SYNCPOINT 保持未设置状态。 在这种情况下,在工作单元协议中包含 get 请求由运行队列管理器的环境确定。 它不是由运行应用程序的环境确定的。 在 z/OS上,获取请求位于工作单元中。 在所有其他环境中,获取请求不在工作单元中。

由于这些差异,要移植的应用程序不得允许此选项为缺省值; 请显式指定 MQGMO_SYNCPOINTMQGMO_NO_SYNCPOINT

此选项对于下列任何选项都无效:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_BROWSE_NEXT
  • MQGMO_LOCK
  • MQGMO_NO_SYNCPOINT
  • MQGMO_SYNCPOINT_IF_PERSISTENT
  • MQGMO_UNLOCK
MQGMO_SYNCPOINT_IF_PERSISTENT
该请求将在正常工作单元协议中运行,但 前提是检索到的消息是持久的。 持久消息在 MQMDPersistence 字段中具有值 MQPER_PERSISTENT
  • 如果消息是持久消息,那么队列管理器会像应用程序已指定 MQGMO_SYNCPOINT一样处理调用。
  • 如果消息不是持久消息,那么队列管理器将处理调用,就像应用程序指定了 MQGMO_NO_SYNCPOINT一样。
此选项对于下列任何选项都无效:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_BROWSE_NEXT
  • MQGMO_COMPLETE_MSG
  • MQGMO_MARK_SKIP_BACKOUT
  • MQGMO_NO_SYNCPOINT
  • MQGMO_SYNCPOINT
  • MQGMO_UNLOCK

此选项在以下连接到这些系统的环境中受支持: AIX®HP-UXz/OSIBM® iSolarisLinux®以及 IBM MQ MQI clients

MQGMO_NO_SYNCPOINT
请求是在正常工作单元协议之外运行。 如果您在没有浏览选项的情况下收到消息,那么将立即从队列中删除该消息。 无法通过回退工作单元使消息再次可用。

如果指定 MQGMO_BROWSE_FIRSTMQGMO_BROWSE_NEXT,那么将采用此选项。

您可以使 MQGMO_SYNCPOINTMQGMO_NO_SYNCPOINT 保持未设置状态。 在这种情况下,在工作单元协议中包含 get 请求由运行队列管理器的环境确定。 它不是由运行应用程序的环境确定的。 在 z/OS上,获取请求位于工作单元中。 在所有其他环境中,获取请求不在工作单元中。

由于这些差异,要移植的应用程序不得允许此选项为缺省值; 请显式指定 MQGMO_SYNCPOINTMQGMO_NO_SYNCPOINT

此选项对于下列任何选项都无效:
  • MQGMO_MARK_SKIP_BACKOUT
  • MQGMO_SYNCPOINT
  • MQGMO_SYNCPOINT_IF_PERSISTENT
MQGMO_MARK_SKIP_BACKOUT
回退工作单元,而不在队列中恢复使用此选项标记的消息。

此选项仅在 z/OS上受支持。

如果指定了此选项,那么还必须指定 MQGMO_SYNCPOINT 。 对于以下任何选项, MQGMO_MARK_SKIP_BACKOUT 都无效:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_BROWSE_NEXT
  • MQGMO_LOCK
  • MQGMO_NO_SYNCPOINT
  • MQGMO_SYNCPOINT_IF_PERSISTENT
  • MQGMO_UNLOCK
注:IMSCICS上,您可能必须在回退包含标记为 MQGMO_MARK_SKIP_BACKOUT的消息的工作单元之后发出外部 IBM MQ 调用。 在落实包含已标记消息的新工作单元之前,必须发出 IBM MQ 调用。 调用可以是您喜欢的任何 IBM MQ 调用。
  1. IMS上,如果尚未应用 IMS APAR PN60855 ,并且您正在运行 IMS MPP 或 BMP 应用程序。
  2. CICS上,如果您正在运行任何应用程序。
在这两种情况下,请在落实包含回退消息的新工作单元之前发出任何 IBM MQ 调用。
注: 在工作单元中,只能有一个标记为跳过回退的 get 请求,以及无任何或多个未标记的 get 请求。

如果应用程序退出工作单元,那么不会将使用 MQGMO_MARK_SKIP_BACKOUT 检索的消息复原到其先前状态。 将回退其他资源更新。 将该消息视为已在由回退请求启动的新工作单元中检索到该消息。 将在不使用 MQGMO_MARK_SKIP_BACKOUT 选项的情况下检索消息。

如果在更改了某些资源之后,工作单元显然无法成功完成,那么 MQGMO_MARK_SKIP_BACKOUT 很有用。 如果省略此选项,那么回退工作单元将恢复队列上的消息。 下次检索消息时,将再次发生相同的事件序列。

但是,如果在原始 MQGET 调用上指定 MQGMO_MARK_SKIP_BACKOUT ,那么回退工作单元会回退对其他资源的更新。 将该消息视为已在新的工作单元下检索。 应用程序可以执行相应的错误处理。 它可以向原始消息的发送方发送报告消息,或者将原始消息放在死信队列上。 然后,它可以落实新的工作单元。 落实新的工作单元将从原始队列中永久除去消息。

MQGMO_MARK_SKIP_BACKOUT 标记单个物理消息。 如果消息属于消息组,那么不会标记该组中的其他消息。 同样,如果标记的消息是逻辑消息的段,那么不会标记逻辑消息中的其他段。

可以标记组中的任何消息,但如果使用 MQGMO_LOGICAL_ORDER检索消息,那么标记组中的第一条消息是有利的。 如果回退工作单元,那么会将第一条 (标记的) 消息移至新的工作单元。 该组中的第二条和更高版本的消息将在队列中恢复。 队列上剩余的消息无法由另一个使用 MQGMO_LOGICAL_ORDER的应用程序检索。 组中的第一条消息不再位于队列中。 但是,支持工作单元的应用程序可以使用 MQGMO_LOGICAL_ORDER 选项将第二条和更高版本的消息检索到新的工作单元中。 已检索到第一条消息。

有时,您可能需要回退新的工作单元。 例如,因为死信队列已满,并且不得废弃消息。 回退新的工作单元将恢复原始队列上的消息,这将防止消息丢失。 但是,在此情况下,无法继续处理。 在回退新的工作单元后,应用程序必须通知操作员或管理员存在不可恢复错误,然后完成。

仅当包含 get 请求的工作单元被应用程序回退中断时, MQGMO_MARK_SKIP_BACKOUT 才有效。 如果由于事务或系统失败而回退了包含获取请求的工作单元,那么将忽略 MQGMO_MARK_SKIP_BACKOUT 。 使用此选项检索的任何消息都将以与不使用此选项检索的消息相同的方式在队列中恢复。

浏览选项: 以下选项与浏览队列中的消息相关:
MQGMO_BROWSE_FIRST
当使用 MQOO_BROWSE 选项打开队列时,将建立浏览游标,该游标在逻辑上位于队列上的第一条消息之前。 然后,可以使用指定 MQGMO_BROWSE_FIRSTMQGMO_BROWSE_NEXTMQGMO_BROWSE_MSG_UNDER_CURSOR 选项的 MQGET 调用以非破坏性方式从队列中检索消息。 浏览光标会标记队列上的消息中的位置,下一个 MQGET 调用 MQGMO_BROWSE_NEXT 将从该位置搜索合适的消息。
对于以下任何选项, MQGMO_BROWSE_FIRST 都无效:
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_BROWSE_NEXT
  • MQGMO_MARK_SKIP_BACKOUT
  • MQGMO_MSG_UNDER_CURSOR
  • MQGMO_SYNCPOINT
  • MQGMO_SYNCPOINT_IF_PERSISTENT
  • MQGMO_UNLOCK
如果未打开队列以进行浏览,那么这也是错误。

带有 MQGMO_BROWSE_FIRSTMQGET 调用将忽略浏览光标的先前位置。 检索队列上满足消息描述符中指定的条件的第一条消息。 消息保留在队列上,浏览光标位于此消息上。

在此调用之后,浏览光标位于已返回的消息上。 在发出下一个带有 MQGMO_BROWSE_NEXTMQGET 调用之前,可能会从队列中除去该消息。 在这种情况下,浏览光标将保留在消息占用的队列中的位置,即使该位置现在为空。

MQGMO_MSG_UNDER_CURSOR 选项与非浏览 MQGET 调用配合使用,以从队列中除去消息。

非浏览 MQGET 调用不会移动浏览光标,即使使用同一 Hobj 句柄也是如此。 它也不会被返回完成代码 MQCC_FAILED或原因码 MQRC_TRUNCATED_MSG_FAILED的浏览 MQGET 调用移动。

指定带有此选项的 MQGMO_LOCK 选项,以锁定浏览的消息。

您可以使用 MQGMO_*MQMO_* 选项的任何有效组合来指定 MQGMO_BROWSE_FIRST ,这些选项用于控制对逻辑消息的组和段中的消息的处理。

如果指定 MQGMO_LOGICAL_ORDER,那么将按逻辑顺序浏览消息。 如果省略该选项,那么将按物理顺序浏览消息。 如果指定 MQGMO_BROWSE_FIRST,那么可以在逻辑顺序和物理顺序之间切换。 使用 MQGMO_BROWSE_NEXT 的后续 MQGET 调用将以与为队列句柄指定 MQGMO_BROWSE_FIRST 的最新调用相同的顺序浏览队列。

队列管理器保留 MQGET 调用的两组组和段信息。 浏览调用的组和段信息与从队列中除去消息的调用的信息分别保留。 如果指定 MQGMO_BROWSE_FIRST,那么队列管理器将忽略要浏览的组和段信息。 它会像没有当前组和当前逻辑消息一样扫描队列。 如果 MQGET 调用成功,完成代码为 MQCC_OKMQCC_WARNING,那么用于浏览的组和段信息将设置为返回的消息的组和段信息。 如果调用失败,那么组和段信息将与调用之前的组和段信息保持相同。

MQGMO_BROWSE_NEXT
将浏览光标前进到队列上满足 MQGET 调用上指定的选择标准的下一条消息。 消息将返回到应用程序,但保留在队列中。
对于以下任何选项, MQGMO_BROWSE_NEXT 都无效:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_MARK_SKIP_BACKOUT
  • MQGMO_MSG_UNDER_CURSOR
  • MQGMO_SYNCPOINT
  • MQGMO_SYNCPOINT_IF_PERSISTENT
  • MQGMO_UNLOCK
如果未打开队列以进行浏览,那么这也是错误。

MQGMO_BROWSE_NEXT 的行为方式与 MQGMO_BROWSE_FIRST相同,如果它是第一次调用以浏览队列,那么在打开队列进行浏览之后。

发出下一个带有 MQGMO_BROWSE_NEXTMQGET 调用之前,可能会从队列中除去光标下的消息。 浏览光标在逻辑上保留在消息占用的队列中的位置,即使该位置现在为空。

消息以两种方式之一存储在队列上:
  • 优先级 ( MQMDS_PRIORITY) 内的 FIFO ,或
  • FIFO 而不考虑 优先级 ( MQMDS_FIFO)
MsgDeliverySequence 队列属性指示应用的方法 (请参阅 队列属性 以获取详细信息)。

队列的 MsgDeliverySequence 可能为 MQMDS_PRIORITY。 消息到达的队列的优先级高于浏览光标当前指向的优先级。 在这种情况下,在使用 MQGMO_BROWSE_NEXT的队列的当前清理期间找不到更高优先级的消息。 只有在使用 MQGMO_BROWSE_FIRST重置浏览光标后,或者通过重新打开队列时,才能找到该值。

如果需要,可以将 MQGMO_MSG_UNDER_CURSOR 选项与非浏览 MQGET 调用配合使用,以从队列中除去消息。

使用同一 Hobj 句柄的非浏览 MQGET 调用不会移动浏览光标。

使用此选项指定 MQGMO_LOCK 选项以锁定已浏览的消息。

您可以使用 MQGMO_*MQMO_* 选项的任何有效组合来指定 MQGMO_BROWSE_NEXT ,这些选项用于控制对逻辑消息的组和段中的消息的处理。

如果指定 MQGMO_LOGICAL_ORDER,那么将按逻辑顺序浏览消息。 如果省略该选项,那么将按物理顺序浏览消息。 如果指定 MQGMO_BROWSE_FIRST,那么可以在逻辑顺序和物理顺序之间切换。 使用 MQGMO_BROWSE_NEXT 的后续 MQGET 调用将以与为队列句柄指定 MQGMO_BROWSE_FIRST 的最新调用相同的顺序浏览队列。 如果不满足此条件,那么调用将失败,原因码为 MQRC_INCONSISTENT_BROWSE

注: 如果未指定 MQGMO_LOGICAL_ORDER ,那么使用 MQGET 调用在消息组结束时进行浏览时,请特别小心。 例如,假设组中的最后一条消息在队列中的组中的第一条消息之前。 使用 MQGMO_BROWSE_NEXT 浏览到组末尾以外的位置,指定 MQMO_MATCH_MSG_SEQ_NUMBER 并将 MsgSeqNumber 设置为 1 将返回组中已浏览的第一条消息。 此结果可能会立即发生,或者如果存在中间组,那么稍后会发生许多 MQGET 调用。 同一注意事项适用于不在组中的逻辑消息。

浏览调用的组和段信息与从队列中除去消息的调用的信息分别保留。

MQGMO_BROWSE_MSG_UNDER_CURSOR
以非破坏性方式检索浏览光标指向的消息,而不考虑在 MQGMOMatchOptions 字段中指定的 MQMO_* 选项。
对于以下任何选项, MQGMO_BROWSE_MSG_UNDER_CURSOR 都无效:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_NEXT
  • MQGMO_MARK_SKIP_BACKOUT
  • MQGMO_MSG_UNDER_CURSOR
  • MQGMO_SYNCPOINT
  • MQGMO_SYNCPOINT_IF_PERSISTENT
  • MQGMO_UNLOCK
如果未打开队列以进行浏览,那么这也是错误。

浏览光标指向的消息是上次使用 MQGMO_BROWSE_FIRSTMQGMO_BROWSE_NEXT 选项检索的消息。 如果自此队列打开以来未对此队列发出任何这些调用,那么该调用将失败。 如果此后以破坏性方式检索了浏览光标下的消息,那么调用也将失败。

此调用不会更改浏览光标的位置。

MQGMO_MSG_UNDER_CURSOR 选项可以与非浏览 MQGET 调用配合使用,以从队列中除去消息。

非浏览 MQGET 调用不会移动浏览光标,即使使用同一 Hobj 句柄也是如此。 它也不会被返回完成代码 MQCC_FAILED或原因码 MQRC_TRUNCATED_MSG_FAILED的浏览 MQGET 调用移动。

如果 MQGMO_BROWSE_MSG_UNDER_CURSORMQGMO_LOCK一起指定:
  • 如果已锁定消息,那么它必须是光标下的消息,因此返回该消息时不会再次解锁和锁定。 消息仍处于锁定状态。
  • 如果没有锁定消息,并且在浏览光标下有消息,那么会将其锁定并返回到应用程序。 如果浏览光标下没有消息,那么调用将失败。
如果在不带 MQGMO_LOCK的情况下指定 MQGMO_BROWSE_MSG_UNDER_CURSOR :
  • 如果已锁定消息,那么它必须是光标下的消息。 该消息将返回到应用程序,然后解锁。 由于该消息现在已解锁,因此无法保证可以再次浏览该消息,或者由同一应用程序以破坏性方式检索该消息。 另一个从队列获取消息的应用程序可能以破坏性方式检索了该消息。
  • 如果没有锁定的消息,并且在浏览光标下有消息,那么会将其返回到应用程序。 如果浏览光标下没有消息,那么调用将失败。

如果 MQGMO_COMPLETE_MSGMQGMO_BROWSE_MSG_UNDER_CURSOR一起指定,那么浏览光标必须标识 MQMD 中的 Offset 字段为零的消息。 如果不满足此条件,那么调用将失败,原因码为 MQRC_INVALID_MSG_UNDER_CURSOR

浏览调用的组和段信息与从队列中除去消息的调用的信息分别保留。

MQGMO_MSG_UNDER_CURSOR
检索浏览光标指向的消息,而不考虑 MQGMOMatchOptions 字段中指定的 MQMO_* 选项。 将从队列中除去该消息。

浏览光标指向的消息是上次使用 MQGMO_BROWSE_FIRSTMQGMO_BROWSE_NEXT 选项检索的消息。

如果 MQGMO_COMPLETE_MSGMQGMO_MSG_UNDER_CURSOR一起指定,那么浏览光标必须标识 MQMD 中的 Offset 字段为零的消息。 如果不满足此条件,那么调用将失败,原因码为 MQRC_INVALID_MSG_UNDER_CURSOR

此选项对于下列任何选项都无效:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_BROWSE_NEXT
  • MQGMO_UNLOCK
如果未同时打开队列以进行浏览和输入,那么这也是错误。 如果浏览光标当前未指向可检索的消息,那么 MQGET 调用将返回错误。
MQGMO_MARK_BROWSE_HANDLE
将标记由成功的 MQGET返回的消息或由返回的 MsgToken标识的消息。 该标记特定于调用中使用的对象句柄。

未从队列中除去消息。

仅当还指定了下列其中一个选项时, MQGMO_MARK_BROWSE_HANDLE 才有效:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_BROWSE_NEXT
对于以下任何选项, MQGMO_MARK_BROWSE_HANDLE 都无效:
  • MQGMO_ALL_MSGS_AVAILABLE
  • MQGMO_ALL_SEGMENTS_AVAILABLE
  • MQGMO_COMPLETE_MSG
  • MQGMO_LOCK
  • MQGMO_LOGICAL_ORDER
  • MQGMO_UNLOCK
消息将保持此状态,直到发生下列其中一个事件为止:
  • 相关的对象句柄已正常或以其他方式关闭。
  • 通过使用选项 MQGMO_UNMARK_BROWSE_HANDLE调用 MQGET 来对此句柄取消标记消息。
  • 将从对破坏性 MQGET的调用返回消息,该调用将使用 MQCC_OKMQCC_WARNING完成。 即使稍后回滚 MQGET ,消息状态也会保持更改。
  • 消息将到期。
MQGMO_MARK_BROWSE_CO_OP
将针对协作集中的所有句柄标记由成功 MQGET返回的消息或由返回的 MsgToken标识的消息。

协作级别标记是对可能已设置的任何句柄级别标记的补充。

未从队列中除去消息。

仅当对指定了 MQOO_CO_OPMQOPEN 的调用返回了所使用的对象句柄时, MQGMO_MARK_BROWSE_CO_OP 才有效。 还必须指定下列其中一个 MQGMO 选项:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
  • MQGMO_BROWSE_NEXT
此选项对于下列任何选项都无效:
  • MQGMO_ALL_MSGS_AVAILABLE
  • MQGMO_ALL_SEGMENTS_AVAILABLE
  • MQGMO_COMPLETE_MSG
  • MQGMO_LOCK
  • MQGMO_LOGICAL_ORDER
  • MQGMO_UNLOCK

如果已标记该消息,并且未指定选项 MQGMO_UNMARKED_BROWSE_MSG ,那么调用将失败,并返回 MQCC_FAILED 和原因码 MQRC_MSG_MARKED_BROWSE_CO_OP

消息将保持此状态,直到发生下列其中一个事件为止:
  • 关闭协作集中的所有对象句柄。
  • 通过使用选项 MQGMO_UNMARK_BROWSE_CO_OP调用 MQGET 来取消对协作浏览器的标记消息。
  • 此消息由队列管理器自动取消标记。
  • 将从对非浏览 MQGET的调用返回消息。 即使稍后回滚 MQGET ,消息状态也会保持更改。
  • 消息将到期。
MQGMO_UNMARKED_BROWSE_MSG
MQGET 的调用 (用于指定 MQGMO_UNMARKED_BROWSE_MSG ) 将返回一条被视为未标记其句柄的消息。 如果将消息标记为其句柄,那么它不会返回消息。 如果队列是通过调用 MQOPEN(使用选项 MQOO_CO_OP) 打开的,并且消息已由协作集的成员标记,那么它也不会返回消息。
此选项对于下列任何选项都无效:
  • MQGMO_ALL_MSGS_AVAILABLE
  • MQGMO_ALL_SEGMENTS_AVAILABLE
  • MQGMO_COMPLETE_MSG
  • MQGMO_LOCK
  • MQGMO_LOGICAL_ORDER
  • MQGMO_UNLOCK
MQGMO_UNMARK_BROWSE_CO_OP
调用指定此选项的 MQGET 后,将不再考虑要为协作集标记的一组协作句柄中的任何打开句柄的消息。 如果在此调用之前将消息标记为句柄级别,那么该消息仍被视为标记为句柄级别。

仅当使用选项 MQOO_CO_OP成功调用 MQOPEN 所返回的句柄时,使用 MQGMO_UNMARK_BROWSE_CO_OP 才有效。 即使消息未被视为由协作的句柄集标记, MQGET 也会成功。

MQGMO_UNMARK_BROWSE_CO_OP 在非浏览 MQGET 调用上无效,或者对于以下任何选项无效:
  • MQGMO_ALL_MSGS_AVAILABLE
  • MQGMO_ALL_SEGMENTS_AVAILABLE
  • MQGMO_COMPLETE_MSG
  • MQGMO_LOCK
  • MQGMO_LOGICAL_ORDER
  • MQGMO_MARK_BROWSE_CO_OP
  • MQGMO_UNLOCK
  • MQGMO_UNMARKED_BROWSE_MSG
MQGMO_UNMARK_BROWSE_HANDLE
在调用指定了此选项的 MQGET 之后,不再将找到的消息视为被此句柄标记。

即使未对此句柄标记消息,调用也会成功。

此选项对非浏览 MQGET 调用无效,或者对下列任何选项无效:
  • MQGMO_ALL_MSGS_AVAILABLE
  • MQGMO_ALL_SEGMENTS_AVAILABLE
  • MQGMO_COMPLETE_MSG
  • MQGMO_LOCK
  • MQGMO_LOGICAL_ORDER
  • MQGMO_MARK_BROWSE_CO_OP
  • MQGMO_UNLOCK
  • MQGMO_UNMARKED_BROWSE_MSG
锁定选项: 以下选项与队列上的锁定消息相关:
MQGMO_LOCK
锁定已浏览的消息,以使该消息对为队列打开的任何其他句柄不可见。 仅当还指定了下列其中一个选项时,才能指定此选项:
  • MQGMO_BROWSE_FIRST
  • MQGMO_BROWSE_NEXT
  • MQGMO_BROWSE_MSG_UNDER_CURSOR
对于每个队列句柄,只能锁定一条消息。 消息可以是逻辑消息或物理消息:
  • 如果指定 MQGMO_COMPLETE_MSG,那么构成逻辑消息的所有消息段都将锁定到队列句柄。 这些消息必须全部存在于队列中,并且可供检索。
  • 如果省略 MQGMO_COMPLETE_MSG,那么仅将单个物理消息锁定到队列句柄。 如果此消息正好是逻辑消息的段,那么锁定段将阻止其他应用程序使用 MQGMO_COMPLETE_MSG 来检索或浏览逻辑消息。

锁定的消息始终是浏览光标下的消息。 稍后指定 MQGMO_MSG_UNDER_CURSOR 选项的 MQGET 调用可将消息从队列中除去。 使用队列句柄的其他 MQGET 调用也可以除去消息 (例如,指定锁定消息的消息标识的调用)。

如果调用返回完成代码 MQCC_FAILEDMQCC_WARNING (原因码为 MQRC_TRUNCATED_MSG_FAILED) ,那么不会锁定任何消息。

如果应用程序未从队列中除去消息,那么将通过下列其中一项操作来释放锁定:
  • 针对此句柄发出另一个 MQGET 调用,指定 MQGMO_BROWSE_FIRSTMQGMO_BROWSE_NEXT。 如果调用通过 MQCC_OKMQCC_WARNING完成,那么将释放锁定。 如果使用 MQCC_FAILED完成调用,那么消息将保持锁定状态。 但是,存在下列例外情况:
    • 如果随 MQRC_TRUNCATED_MSG_FAILED一起返回了 MQCC_WARNING ,那么不会解锁该消息。
    • 如果随 MQRC_NO_MSG_AVAILABLE一起返回 MQCC_FAILED ,那么将解锁该消息。

    如果还指定了 MQGMO_LOCK,那么将锁定返回的消息。 如果省略 MQGMO_LOCK,那么在调用后没有锁定消息。

    如果指定 MQGMO_WAIT,并且没有立即可用的消息,那么将在启动等待之前解锁原始消息。

  • 使用 MQGMO_BROWSE_MSG_UNDER_CURSOR对此句柄发出另一个 MQGET 调用,而不使用 MQGMO_LOCK。 如果调用通过 MQCC_OKMQCC_WARNING完成,那么将释放锁定。 如果使用 MQCC_FAILED完成调用,那么消息将保持锁定状态。 但是,以下异常适用:
    • 如果随 MQRC_TRUNCATED_MSG_FAILED一起返回了 MQCC_WARNING ,那么不会解锁该消息。
  • 使用 MQGMO_UNLOCK对此句柄发出另一个 MQGET 调用。
  • 使用句柄发出 MQCLOSE 调用。 MQCLOSE 可能是隐式的,由应用程序结束导致。
指定 MQGMO_LOCK( MQOO_BROWSE除外) 不需要特殊的 MQOPEN 选项,而指定附带的浏览选项需要此选项。
对于以下任何选项, MQGMO_LOCK 都无效:
  • MQGMO_MARK_SKIP_BACKOUT
  • MQGMO_SYNCPOINT
  • MQGMO_SYNCPOINT_IF_PERSISTENT
  • MQGMO_UNLOCK

当您在 HP Integrity NonStop Server 上对 z/OS 队列管理器使用 IBM MQ 客户机 (由 TMF 协调) 时,无法使用 MQGMO_LOCK

MQGMO_UNLOCK
要解锁的消息必须先前已由带有 MQGMO_LOCK 选项的 MQGET 调用锁定。 如果没有针对此句柄锁定的消息,那么调用将通过 MQCC_WARNINGMQRC_NO_MSG_LOCKED完成。

如果指定 MQGMO_UNLOCK,那么不会检查或变更 MsgDescBufferLengthBufferDataLength 参数。 Buffer中未返回任何消息。

无需特殊打开选项即可指定 MQGMO_UNLOCK (尽管首先需要 MQOO_BROWSE 来发出锁定请求)。

此选项对除以下选项以外的任何选项都无效:
  • MQGMO_NO_WAIT
  • MQGMO_NO_SYNCPOINT
无论是否指定了这两个选项,都将采用这两个选项。
消息-数据选项: 以下选项与从队列中读取消息时消息数据的处理相关:
MQGMO_ACCEPT_TRUNCATED_MSG
如果消息缓冲区太小而无法保存完整消息,请允许 MQGET 调用填充该缓冲区。 MQGET 将尽可能多的消息填充到缓冲区中。 它会发出警告完成代码,并完成其处理。 这表示:
  • 浏览消息时,浏览光标将前进到返回的消息。
  • 除去消息时,将从队列中除去返回的消息。
  • 如果未发生其他错误,那么将返回原因码 MQRC_TRUNCATED_MSG_RECEIVED。
如果没有此选项,那么缓冲区仍会填充尽可能多的消息。 发出了警告完成代码,但未完成处理。 这表示:
  • 浏览消息时,浏览光标不高级。
  • 除去消息时,不会从队列中除去消息。
  • 如果未发生其他错误,那么将返回原因码 MQRC_TRUNCATED_MSG_FAILED
MQGMO_CONVERT
此选项会将消息中的应用程序数据转换为符合 MQGET 调用的 MsgDesc 参数中指定的 CodedCharSetIdEncoding 值。 在将数据复制到 Buffer 参数之前,将对其进行转换。
转换过程假定在放入消息时指定的 Format 字段用于标识消息中数据的性质。 消息数据由队列管理器针对内置格式进行转换,并由用户编写的出口针对其他格式进行转换。 有关数据转换出口的详细信息,请参阅 数据转换出口
  • 如果转换成功,那么在从 MQGET 调用返回时, MsgDesc 参数中指定的 CodedCharSetIdEncoding 字段保持不变。
  • 如果仅转换失败,那么将返回未转换的消息数据。 MsgDesc 中的 CodedCharSetIdEncoding 字段将设置为未转换的消息的值。 在此情况下,完成代码为 MQCC_WARNING
在任一情况下,这些字段都描述 Buffer 参数中返回的消息数据的字符集标识和编码。

请参阅 MQMD-消息描述符 中描述的 Format 字段,以获取队列管理器为其执行转换的格式名称的列表。

组和段选项: 以下选项与逻辑消息的组和段中的消息处理相关。 在选项描述之前,以下是一些重要术语的定义:
物理消息
物理消息是可以放在队列上或从队列中除去的最小信息单元。 它通常对应于在单个 MQPUTMQPUT1MQGET 调用上指定或检索的信息。 每条物理消息都有自己的消息描述符 MQMD。 通常,物理消息通过消息标识的不同值 ( MQMD中的 MsgId 字段) 进行区分。 队列管理器不会强制实施不同的值。
逻辑消息
逻辑消息是应用程序信息的单个单元。 在没有系统约束的情况下,逻辑消息与物理消息相同。 如果逻辑消息很大,那么系统约束可能建议或需要将逻辑消息拆分为两个或多个物理消息 (称为段)。

已分段的逻辑消息由两个或更多具有相同非空组标识的物理消息 ( MQMD中的 GroupId 字段) 组成。 它们具有相同的消息序号,即 MQMD中的 MsgSeqNumber 字段。 通过 MQMD中的段偏移量 Offset 字段的不同值来区分段。 段偏移是物理消息中的数据从逻辑消息中的数据开始的偏移量。 由于每个段都是物理消息,因此逻辑消息中的段通常具有不同的消息标识。

未分段但发送应用程序允许分段的逻辑消息也具有非空组标识。 在这种情况下,如果逻辑消息不属于消息组,那么只有一条具有该组标识的物理消息。 发送应用程序已禁止分段的逻辑消息具有空组标识 MQGI_NONE,除非逻辑消息属于消息组。

消息组
消息组是一组具有相同非空组标识的一个或多个逻辑消息。 该组中的逻辑消息通过消息序号的不同值进行区分。 序号是 1 到 n 范围内的整数,其中 n 是组中的逻辑消息数。 如果对一条或多条逻辑消息进行分段,那么组中的物理消息数超过 n 条。
MQGMO_LOGICAL_ORDER
MQGMO_LOGICAL_ORDER 控制队列句柄的连续 MQGET 调用返回消息的顺序。 必须在每个调用上指定该选项。

如果为同一队列句柄的连续 MQGET 调用指定了 MQGMO_LOGICAL_ORDER ,那么将按消息序号的顺序返回组中的消息。 逻辑消息的段按其段偏移量给定的顺序返回。 此顺序可能与这些消息和段在队列中出现的顺序不同。

注: 指定 MQGMO_LOGICAL_ORDER 不会对不属于组且不属于段的消息产生不利影响。 实际上,这类消息被视为属于仅由一条消息组成的消息组。 从包含组,消息段和非组中的未分段消息的混合消息的队列中检索消息时,可以安全地指定 MQGMO_LOGICAL_ORDER

要按所需顺序返回消息,队列管理器会在连续的 MQGET 调用之间保留组和段信息。 组和段信息标识队列句柄的当前消息组和当前逻辑消息。 它还标识组和逻辑消息中的当前位置,以及是否在工作单元中检索消息。 由于队列管理器保留此信息,因此应用程序无需在每次 MQGET 调用之前设置组和段信息。 具体而言,这意味着应用程序不需要在 MQMD中设置 GroupIdMsgSeqNumberOffset 字段。 但是,应用程序必须在每个调用上正确设置 MQGMO_SYNCPOINTMQGMO_NO_SYNCPOINT 选项。

当队列打开时,没有当前消息组和当前逻辑消息。 当 MQGET 调用返回具有 MQMF_MSG_IN_GROUP 标志的消息时,消息组将成为当前消息组。 在连续调用上指定了 MQGMO_LOGICAL_ORDER 时,该组将保留当前组,直到返回具有以下内容的消息为止:
  • MQMF_LAST_MSG_IN_GROUP without MQMF_SEGMENT (即,组中的最后一条逻辑消息未分段) ,或者
  • 带有 MQMF_LAST_SEGMENTMQMF_LAST_MSG_IN_GROUP (即,返回的消息是组中最后一条逻辑消息的最后一段)。
返回此类消息时,将终止消息组,并且在成功完成 MQGET 调用时,不再存在当前组。 以类似方式,当 MQGET 调用返回具有 MQMF_SEGMENT 标志的消息时,逻辑消息将成为当前逻辑消息。 当返回具有 MQMF_LAST_SEGMENT 标志的消息时,将终止逻辑消息。
如果未指定选择标准,那么后续 MQGET 调用将以正确的顺序返回队列中第一个消息组的消息。 然后,它们将返回第二个消息组的消息,依此类推,直到没有更多消息可用为止。 可以通过在 MatchOptions 字段中指定以下一个或多个选项来选择返回的特定消息组:
  • MQMO_MATCH_MSG_ID
  • MQMO_MATCH_CORREL_ID
  • MQMO_MATCH_GROUP_ID
但是,仅当没有当前消息组或逻辑消息时,这些选项才有效。 请参阅 MQGMO-Get-message 选项 中描述的 MatchOptions 字段,以获取更多详细信息。
表 2 显示队列管理器在尝试查找要在 MQGET 调用上返回的消息时查找的 MsgIdCorrelIdGroupIdMsgSeqNumberOffset 字段的值。 这些规则既适用于从队列中除去消息,也适用于在队列中浏览消息。 在表中,表示 "是" 或 "否":
LOG ORD
指示是否在调用上指定了 MQGMO_LOGICAL_ORDER 选项。
Cur grp
指示在调用之前是否存在当前消息组。
Cur log msg
指示在调用之前是否存在当前逻辑消息。
其他列
显示队列管理器要查找的值。 "先前" 表示针对队列句柄的先前消息中的字段返回的值。
表 2. 与逻辑消息组和段中的消息相关的 MQGET 选项
指定的选项 调用前的组和 log-msg 状态 队列管理器查找的值
LOG ORD Cur grp Cur log msg MsgId CorrelId GroupId MsgSeqNumber Offset
Yes 控制者 MatchOptions 控制者 MatchOptions 控制者 MatchOptions 1 0
Yes Yes 任何消息标识 任何相关标识 上一个组标识 1 前一个偏移量 + 前一个段长
Yes Yes 任何消息标识 任何相关标识 上一个组标识 前一个序列号 + 1 0
Yes Yes Yes 任何消息标识 任何相关标识 上一个组标识 前一个序列号 前一个偏移量 + 前一个段长
任一 任一 控制者 MatchOptions 控制者 MatchOptions 控制者 MatchOptions 控制者 MatchOptions 控制者 MatchOptions

如果队列上存在多个符合返回条件的消息组,那么将按每个组中第一条逻辑消息的第一段在队列上的位置确定的顺序返回这些组。 即,消息序号为 1 且偏移量为 0 的物理消息确定返回合格组的顺序。

MQGMO_LOGICAL_ORDER 选项影响工作单元,如下所示:
  • 如果在工作单元中检索组中的第一个逻辑消息或段,那么必须在工作单元中检索组中的所有其他逻辑消息和段 (如果使用相同的队列句柄)。 但是,不需要在同一工作单元中检索这些信息。 这允许在队列句柄的两个或多个连续工作单元之间拆分由许多物理消息组成的消息组。
  • 如果 在工作单元中检索组中的第一个逻辑消息或段,并且使用相同的队列句柄,那么不能在工作单元中检索组中的任何其他逻辑消息和段。
如果不满足这些条件,那么 MQGET 调用将失败,原因码为 MQRC_INCONSISTENT_UOW

指定 MQGMO_LOGICAL_ORDER 时,在 MQGET 调用上提供的 MQGMO 不得小于 MQGMO_VERSION_2,并且 MQMD 不得小于 MQMD_VERSION_2。 如果未满足此条件,那么调用将失败,原因码为 MQRC_WRONG_GMO_VERSIONMQRC_WRONG_MD_VERSION(视情况而定)。

如果对队列句柄的连续 MQGET 调用 指定 MQGMO_LOGICAL_ORDER ,那么将返回消息而不考虑它们是属于消息组还是属于逻辑消息段。 这意味着可能会返回来自特定组或逻辑消息的消息或段,或者与来自其他组或逻辑消息的消息或段混合,或者与不在组中且不是段的消息混合。 在这种情况下,后续 MQGET 调用返回的特定消息由这些调用上指定的 MQMO_* 选项控制 (请参阅 MQGMO-Get-message 选项 中描述的 MatchOptions 字段以获取这些选项的详细信息)。

这是在发生系统故障后,可用于在中间重新启动消息组或逻辑消息的方法。 当系统重新启动时,应用程序可以将 GroupIdMsgSeqNumberOffsetMatchOptions 字段设置为相应的值,然后在设置了 MQGMO_SYNCPOINTMQGMO_NO_SYNCPOINT 的情况下发出 MQGET 调用,但 指定 MQGMO_LOGICAL_ORDER。 如果此调用成功,那么队列管理器将保留组和段信息,并且使用该队列句柄的后续 MQGET 调用可正常指定 MQGMO_LOGICAL_ORDER

队列管理器为 MQGET 调用保留的组和段信息与为 MQPUT 调用保留的组和段信息不同。 此外,队列管理器还会保留以下项的单独信息:
  • 从队列中除去消息的 MQGET 调用。
  • MQGET 调用,用于浏览队列上的消息。
对于任何给定的队列句柄,应用程序可以将指定 MQGMO_LOGICAL_ORDERMQGET 调用与不指定的 MQGET 调用混合使用。 但是,请注意以下几点:
  • 如果省略 MQGMO_LOGICAL_ORDER,那么每次成功的 MQGET 调用都会导致队列管理器将保存的组和段信息设置为与返回的消息对应的值; 这将替换队列管理器为队列句柄保留的现有组和段信息。 仅修改与调用操作 (浏览或除去) 相应的信息。
  • 如果省略 MQGMO_LOGICAL_ORDER,那么如果存在当前消息组或逻辑消息,那么调用不会失败; 调用可能成功,并带有 MQCC_WARNING 完成代码。 表 3 显示了可能出现的各种个案。 在这些情况下,如果完成代码不是 MQCC_OK,那么原因码为下列其中一项 (视情况而定):
    • MQRC_INCOMPLETE_GROUP
    • MQRC_INCOMPLETE_MSG
    • MQRC_INCONSISTENT_UOW
    注: 队列管理器在浏览队列时,或在关闭已打开进行浏览但未输入的队列时,不会检查组和段信息; 在这些情况下,完成代码始终为 MQCC_OK (假定没有其他错误)。
表 3. MQGET 或 MQCLOSE 调用与组和段信息不一致时的结果
当前调用是 先前的调用是 MQGET with MQGMO_LOGICAL_ORDER 先前调用为 MQGET ,但没有 MQGMO_LOGICAL_ORDER
MQGMO_LOGICAL_ORDERMQGET MQCC_FAILED MQCC_FAILED
不带 MQGMO_LOGICAL_ORDERMQGET MQCC_WARNING MQCC_OK
MQCLOSE,使用未结束的组或逻辑消息 MQCC_WARNING MQCC_OK

建议要按逻辑顺序检索消息和段的应用程序指定 MQGMO_LOGICAL_ORDER,因为这是要使用的最简单选项。 该选项可使应用程序无需管理组和段信息,因为队列管理器会管理此信息。 但是,与 MQGMO_LOGICAL_ORDER 选项提供的控制相比,专用应用程序可能需要更多的控制,而这可以通过不指定该选项来实现。 然后,应用程序必须确保在每个 MQGET 调用之前正确设置 MQMD中的 MsgIdCorrelIdGroupIdMsgSeqNumberOffset 字段以及 MQGMO中的 MatchOptions 中的 MQMO_* 选项。

例如,要 转发 它接收的物理消息 (而不考虑这些消息是在逻辑消息的组还是段中) 的应用程序 不得 指定 MQGMO_LOGICAL_ORDER。 在发送和接收队列管理器间具有多条路径的复杂网络中,物理消息到达时可能杂乱无序。 通过在 MQPUT 调用上既不指定 MQGMO_LOGICAL_ORDER,也不指定相应的 MQPMO_LOGICAL_ORDER ,转发应用程序可以在到达时立即检索和转发每条物理消息,而不必按逻辑顺序等待下一条消息到达。

您可以将 MQGMO_LOGICAL_ORDER 与任何其他 MQGMO_* 选项一起指定,并在适当情况下将其与各种 MQMO_* 选项一起指定 (请参阅前面的部分)。
  • z/OS上,专用队列和共享队列支持此选项,但队列必须具有索引类型 MQIT_GROUP_ID。 对于共享队列,队列映射到的 CFSTRUCT 对象必须处于 CFLEVEL (3) 或更高级别。
  • AIXHP-UXIBM iSolarisLinuxWindows以及连接到这些系统的 IBM MQ MQI clients 上,所有本地队列都支持此选项。
MQGMO_COMPLETE_MSG
MQGET 调用只能返回完整的逻辑消息。 如果逻辑消息已分段,那么队列管理器将重新组合这些段并将完整的逻辑消息返回给应用程序; 对于检索该逻辑消息的应用程序而言,逻辑消息已分段这一事实并不明显。
注: 这是导致队列管理器重新组装消息段的唯一选项。 如果未指定,那么段将单独返回到应用程序 (如果它们存在于队列中) (并且它们满足在 MQGET 调用上指定的其他选择标准)。 不希望接收个别段的应用程序必须始终指定 MQGMO_COMPLETE_MSG

要使用此选项,应用程序必须提供足以容纳完整消息的缓冲区,或者指定 MQGMO_ACCEPT_TRUNCATED_MSG 选项。

如果队列包含缺少部分段的分段消息 (可能是因为它们在网络中已延迟并且尚未到达) ,那么指定 MQGMO_COMPLETE_MSG 将阻止检索属于不完整逻辑消息的段。 但是,这些消息段仍构成 CurrentQDepth 队列属性的值; 这意味着可能没有可检索的逻辑消息,即使 CurrentQDepth 大于零也是如此。

对于 持久 消息,队列管理器只能在工作单元中重新组合段:
  • 如果 MQGET 调用在用户定义的工作单元中运行,那么将使用该工作单元。 如果在重新组装过程中调用失败,那么队列管理器会在队列中恢复在重新组装期间除去的任何段。 但是,此故障不会阻止成功落实工作单元。
  • 如果调用在用户定义的工作单元外部运行,并且不存在用户定义的工作单元,那么队列管理器将在调用期间创建工作单元。 如果调用成功,那么队列管理器将自动落实工作单元 (应用程序不需要执行此操作)。 如果调用失败,那么队列管理器将回退工作单元。
  • 如果调用在用户定义的工作单元外部运行,但存在用户定义的工作单元,那么队列管理器无法重新组合。 如果消息不需要重新组装,那么调用仍可成功。 但是,如果消息需要重新组装,那么调用将失败,原因码为 MQRC_UOW_NOT_AVAILABLE

对于 非持久 消息,队列管理器不需要工作单元即可执行重新组装。

作为段的每条物理消息都有自己的消息描述符。 对于构成单个逻辑消息的段,消息描述符中的大多数字段对于逻辑消息中的所有段都是相同的; 通常只有 MsgIdOffsetMsgFlags 字段在逻辑消息中的段之间有所不同。 但是,如果将段放在中间队列管理器中的死信队列上,那么 DLQ 处理程序将检索指定 MQGMO_CONVERT 选项的消息,这可能会导致更改段的字符集或编码。 如果 DLQ 处理程序在途中成功发送段,那么段可能具有与逻辑消息中的其他段不同的字符集或编码 (当段到达目标队列管理器时)。

CodedCharSetIdEncoding 字段不同的段组成的逻辑消息无法由队列管理器重新组合为单个逻辑消息。 相反,队列管理器会在逻辑消息开头重新组合并返回前几个连续段,这些段具有相同的字符集标识和编码,并且 MQGET 调用将完成代码为 MQCC_WARNING ,原因码为 MQRC_INCONSISTENT_CCSIDSMQRC_INCONSISTENT_ENCODINGS(视情况而定)。 无论是否指定了 MQGMO_CONVERT ,都会发生此情况。 要检索其余段,应用程序必须在不使用 MQGMO_COMPLETE_MSG 选项的情况下重新发出 MQGET 调用,逐个检索段。 MQGMO_LOGICAL_ORDER 可用于按顺序检索其余段。

放置段的应用程序还可以将消息描述符中的其他字段设置为不同段之间不同的值。 但是,如果接收应用程序使用 MQGMO_COMPLETE_MSG 来检索逻辑消息,那么执行此操作没有任何优势。 当队列管理器重新组装逻辑消息时,它会在消息描述符中返回来自 第一个 段的消息描述符的值; 唯一的例外是 MsgFlags 字段,队列管理器设置此字段以指示重新组装的消息是唯一的段。

如果为报告消息指定了 MQGMO_COMPLETE_MSG ,那么队列管理器将执行特殊处理。 队列管理器检查队列以查看与逻辑消息中的不同段相关的该报告类型的所有报告消息是否都存在于队列中。 如果是,那么可以通过指定 MQGMO_COMPLETE_MSG将它们作为单一消息进行检索。 要实现此目的,必须由支持分段的队列管理器或 MCA 生成报告消息,或者发端应用程序必须请求至少 100 字节的消息数据 (即,必须指定相应的 MQRO_*_WITH_DATAMQRO_*_WITH_FULL_DATA 选项)。 如果存在的应用程序数据量小于段的完整数据量,那么将在返回的报告消息中使用空值替换缺少的字节。

如果 MQGMO_COMPLETE_MSGMQGMO_MSG_UNDER_CURSORMQGMO_BROWSE_MSG_UNDER_CURSOR一起指定,那么浏览光标必须位于 MQMDOffset 字段的值为 0 的消息上。 如果不满足此条件,那么调用将失败,原因码为 MQRC_INVALID_MSG_UNDER_CURSOR

MQGMO_COMPLETE_MSG 意味着 MQGMO_ALL_SEGMENTS_AVAILABLE,因此不需要指定。

可以使用除 MQGMO_SYNCPOINT_IF_PERSISTENT以外的任何其他 MQGMO_* 选项以及除 MQMO_MATCH_OFFSET 以外的任何 MQMO_* 选项来指定 MQGMO_COMPLETE_MSG
  • z/OS上,专用队列和共享队列支持此选项,但队列的索引类型必须为 MQIT_GROUP_ID。 对于共享队列,队列映射到的 CFSTRUCT 对象必须处于 CFLEVEL (3) 或更高级别。
  • AIXHP-UXIBM iSolarisLinuxWindows以及连接到这些系统的 IBM MQ MQI clients 上,所有本地队列都支持此选项。
MQGMO_ALL_MSGS_AVAILABLE
仅当组中的 所有 消息都可用时,组中的消息才可供检索。 如果队列包含缺少某些消息的消息组 (可能是因为这些消息在网络中已延迟并且尚未到达) ,那么指定 MQGMO_ALL_MSGS_AVAILABLE 将阻止检索属于不完整组的消息。 但是,这些消息仍构成 CurrentQDepth 队列属性的值; 这意味着可能没有可检索的消息组,即使 CurrentQDepth 大于零也是如此。 如果没有其他可检索的消息,那么将在指定的等待时间间隔 (如果有) 到期后返回原因码 MQRC_NO_MSG_AVAILABLE
MQGMO_ALL_MSGS_AVAILABLE 的处理取决于是否还指定了 MQGMO_LOGICAL_ORDER :
  • 如果同时指定了这两个选项,那么当没有当前组或逻辑消息时, MQGMO_ALL_MSGS_AVAILABLE 有效。 如果存在 当前组或逻辑消息,那么将忽略 MQGMO_ALL_MSGS_AVAILABLE 。 这意味着在按逻辑顺序处理消息时, MQGMO_ALL_MSGS_AVAILABLE 可以保持开启状态。
  • 如果在不带 MQGMO_LOGICAL_ORDER的情况下指定 MQGMO_ALL_MSGS_AVAILABLE ,那么 MQGMO_ALL_MSGS_AVAILABLE 始终 具有作用。 这意味着必须在从队列中除去组中的第一条消息之后关闭该选项,以便能够除去组中的其余消息。

成功完成指定 MQGMO_ALL_MSGS_AVAILABLEMQGET 调用意味着在发出 MQGET 调用时,组中的所有消息都在队列中。 但是,请注意,其他应用程序仍可以从组中除去消息 (该组未锁定到检索组中第一条消息的应用程序)。

如果省略此选项,那么即使组不完整,也可以检索属于组的消息。

MQGMO_ALL_MSGS_AVAILABLE 意味着 MQGMO_ALL_SEGMENTS_AVAILABLE,因此不需要指定。

可以使用任何其他 MQGMO_* 选项以及任何 MQMO_* 选项来指定 MQGMO_ALL_MSGS_AVAILABLE
  • z/OS上,专用队列和共享队列支持此选项,但队列的索引类型必须为 MQIT_GROUP_ID。 对于共享队列,队列映射到的 CFSTRUCT 对象必须处于 CFLEVEL (3) 或更高级别。
  • AIXHP-UXIBM iSolarisLinuxWindows以及连接到这些系统的 IBM MQ MQI clients 上,所有本地队列都支持此选项。
MQGMO_ALL_SEGMENTS_AVAILABLE
仅当逻辑消息中的 所有 段都可用时,逻辑消息中的段才可供检索。 如果队列包含缺少部分段的分段消息 (可能是因为它们在网络中已延迟并且尚未到达) ,那么指定 MQGMO_ALL_SEGMENTS_AVAILABLE 将阻止检索属于不完整逻辑消息的段。 但是,这些段仍构成 CurrentQDepth 队列属性的值; 这意味着可能没有可检索的逻辑消息,即使 CurrentQDepth 大于零也是如此。 如果没有其他可检索的消息,那么将在指定的等待时间间隔 (如果有) 到期后返回原因码 MQRC_NO_MSG_AVAILABLE

MQGMO_ALL_SEGMENTS_AVAILABLE 的处理取决于是否还指定了 MQGMO_LOGICAL_ORDER :
  • 如果同时指定了这两个选项,那么当没有当前逻辑消息时, MQGMO_ALL_SEGMENTS_AVAILABLE 有效。 如果存在 当前逻辑消息,那么将忽略 MQGMO_ALL_SEGMENTS_AVAILABLE 。 这意味着在按逻辑顺序处理消息时, MQGMO_ALL_SEGMENTS_AVAILABLE 可以保持开启状态。
  • 如果在不带 MQGMO_LOGICAL_ORDER的情况下指定 MQGMO_ALL_SEGMENTS_AVAILABLE ,那么 MQGMO_ALL_SEGMENTS_AVAILABLE 始终 具有作用。 这意味着必须在从队列中除去逻辑消息中的第一个段之后关闭该选项,以便能够除去逻辑消息中的其余段。

如果未指定此选项,那么即使逻辑消息不完整,也可以检索消息段。

虽然 MQGMO_COMPLETE_MSGMQGMO_ALL_SEGMENTS_AVAILABLE 都要求所有段都可用,然后才能检索它们中的任何段,但前者返回完整的消息,而后者允许逐个检索这些段。

如果为报告消息指定了 MQGMO_ALL_SEGMENTS_AVAILABLE ,那么队列管理器将检查该队列,以查看组成完整逻辑消息的每个分段是否至少有一条报告消息。 如果存在,那么满足 MQGMO_ALL_SEGMENTS_AVAILABLE 条件。 但是,队列管理器不会检查存在的报告消息的 类型 ,因此报告消息中可能混用了与逻辑消息段相关的报告类型。 因此, MQGMO_ALL_SEGMENTS_AVAILABLE 的成功并不意味着 MQGMO_COMPLETE_MSG 将成功。 如果存在 为特定逻辑消息的段提供的报告类型的混合,那么必须逐个检索这些报告消息。

您可以使用任何其他 MQGMO_* 选项以及任何 MQMO_* 选项来指定 MQGMO_ALL_SEGMENTS_AVAILABLE
  • z/OS上,专用队列和共享队列支持此选项,但队列的索引类型必须为 MQIT_GROUP_ID。 对于共享队列,队列映射到的 CFSTRUCT 对象必须处于 CFLEVEL (3) 或更高级别。
  • AIXHP-UXIBM iSolarisLinuxWindows以及连接到这些系统的 IBM MQ MQI clients 上,所有本地队列都支持此选项。
属性选项:下列选项与消息的属性相关:
MQGMO_PROPERTIES_AS_Q_DEF

消息的属性 (消息描述符 (或扩展) 中包含的属性除外) 应由 PropertyControl 队列属性定义。 如果提供了 MsgHandle ,那么除非 PropertyControl 队列属性的值为 MQPROP_FORCE_MQRFH2,否则将忽略此选项并通过 MsgHandle提供消息属性。

如果未指定属性选项,那么这是缺省操作。

MQGMO_PROPERTIES_IN_HANDLE

应通过 MsgHandle提供消息的属性。 如果未提供消息句柄,那么调用将失败,原因为 MQRC_HMSG_ERROR

注: 如果消息稍后由未创建消息句柄的应用程序读取,那么队列管理器会将任何消息属性放入 MQRFH2 结构中。 您可能会发现存在意外的 MQRFH2 头会破坏现有应用程序的行为。
MQGMO_NO_PROPERTIES

将不会检索消息的属性,但包含在消息描述符 (或扩展) 中的属性除外。 如果提供了 MsgHandle ,那么将忽略该值。

MQGMO_PROPERTIES_FORCE_MQRFH2

应该使用 MQRFH2 头来表示消息的属性 (消息描述符 (或扩展) 中包含的属性除外)。 对于期望检索属性但无法更改为使用消息句柄的应用程序,这将提供与先前版本的兼容性。 如果 MsgHandle 已提供,那么会将其忽略。

MQGMO_PROPERTIES_COMPATIBILITY
如果消息包含前缀为 "mcd.""jms.""usr.""mqext."的属性,那么所有消息属性都将通过 MQRFH2 头传递到应用程序。 否则,将废弃除消息描述符(或扩展)中包含的属性之外的所有消息属性,并且应用程序再也无法访问这些属性。
缺省选项: 如果不需要所描述的任何选项,那么可以使用以下选项:
MQGMO_NONE
使用此值来指示未指定任何其他选项;所有选项均采用其缺省值。 MQGMO_NONE 辅助程序文档; 不打算将此选项与任何其他选项一起使用,但由于其值为零,因此无法检测到此类使用。

Options 字段的初始值为 MQGMO_NO_WAIT 加号 MQGMO_PROPERTIES_AS_Q_DEF

1 指定 MQGMO_LOCK 选项的 MQGET 调用被视为非浏览调用。