使用 MQPUT 调用将消息放置到本地队列上

使用此信息以了解如何使用 MQPUT 调用将消息放置到本地队列上。

作为 MQPUT 调用的输入,必须提供:
  • 连接句柄 (Hconn)。
  • 队列句柄 (Hobj)。
  • 要放置到队列上的消息的描述。 此消息采用消息描述符结构 (MQMD) 的形式。
  • 控制信息,采用放置消息选项结构 (MQPMO) 的形式。
  • 消息中包含的数据的长度 (MQLONG)。
  • 消息数据本身。
MQPUT 调用的输出如下所示:
  • 原因码 (MQLONG)
  • 完成代码 (MQLONG)

如果调用成功完成,那么还会返回选项结构以及消息描述符结构。 调用修改选项结构以显示要向其发送消息的队列的名称和队列管理器的名称。 如果请求队列管理器为将放置的消息的标识生成唯一值(通过在 MQMD 结构的 MsgId 字段中指定二进制零),那么调用会先在 MsgId 字段中插入值,再向您返回此结构。 发出另一个 MQPUT 之前重置此值。

MQPUT中有 MQPUT 调用的描述。

有关作为 MQPUT 调用的输入所需的信息的更多描述,请参见以下链接:

指定句柄

对于 z/OS® 应用程序上的 CICS® 中的连接句柄 (Hconn) ,可以指定常量 MQHC_DEF_HCONN (其值为零) ,也可以使用 MQCONN 或 MQCONNX 调用返回的连接句柄。 对于其他应用程序,始终使用 MQCONN 或 MQCONNX 调用返回的连接句柄。

无论您处于什么环境,请使用 MQOPEN 调用返回的相同队列句柄 (Hobj)。

使用 MQMD 结构定义消息

消息描述符结构 (MQMD) 是 MQPUT 和 MQPUT1 调用的输入/输出参数。 使用它来定义要放置到队列上的消息。

如果为消息指定了 MQPRI_PRIORITY_AS_Q_DEF 或 MQPER_PERSISTENCE_AS_Q_DEF 且队列是集群队列,那么使用的值为 MQPUT 解析为的队列的值。 如果对此队列禁用 MQPUT,那么调用会失败。 请参阅 配置队列管理器集群 以获取更多信息。

注: 在放入新消息之前,请使用 MQPMO_NEW_MSG_ID 和 MQPMO_NEW_CORREL_ID ,以确保 MsgIdCorrelId 唯一。 成功执行 MQPUT 时,会返回这些字段中的值。

提供了 MQMD 在 IBM MQ 消息中描述的消息属性的简介,并且在 MQMD中提供了结构本身的描述。

使用 MQPMO 结构指定选项

使用 MQPMO(放置消息选项)结构将选项传递到 MQPUT 和 MQPUT1 调用。

以下部分为您提供填充此结构的字段的帮助。 MQPMO中有结构的描述。

此结构包含以下字段:
  • StrucId
  • Version
  • Options
  • Context
  • ResolvedQName
  • ResolvedQMgrName
  • RecsPresent
  • PutMsgRecsFields
  • ResponseRecOffset and ResponseRecPtr
  • OriginalMsgHandle
  • NewMsgHandle
  • Action
  • PubLevel
这些字段的内容如下所示:
StrucId
此字段将结构标识为放置消息选项结构。 这是一个 4 字符的字段。 始终指定 MQPMO_STRUC_ID。
版本
这描述了结构的版本号。 缺省值为 MQPMO_VERSION_1。 如果输入 MQPMO_VERSION_2,那么可以使用分发列表 (请参阅 分发列表 )。 如果输入 MQPMO_VERSION_3,那么可使用消息句柄和消息属性。 如果输入 MQPMO_CURRENT_VERSION,那么应用程序始终设置为使用最新级别。
选项
此字段控制以下内容:
  • 是否在工作单元中包含放置操作
  • 将多少上下文信息与消息关联
  • 从其中获取上下文信息的位置
  • 调用在队列管理器处于停顿状态时是否会失败
  • 是否允许分组或分段
  • 生成新消息标识和相关标识
  • 将消息和分段放置到队列上的顺序
  • 是否解析本地队列名称

如果将 Options 字段保留设置为缺省值 (MQPMO_NONE),那么放置的消息具有关联的缺省上下文信息。

此外,调用采用同步点运行的方式由平台确定。 在 z/OS 中,同步点控制缺省值为 yes; 对于其他平台,缺省值为 no。

Context
此字段说明希望从其复制上下文信息(如果在 Options 字段中请求)的队列句柄的名称。

有关消息上下文的简介,请参阅 消息上下文。 有关使用 MQPMO 结构来控制消息中的上下文信息的信息,请参阅 控制消息上下文信息

ResolvedQName
此字段包含为接收消息而打开的队列的名称(解析任何别名后)。 这是输出字段。
ResolvedQMgrName
此字段包含在 ResolvedQName 中拥有队列的队列管理器的名称(在解析任何别名后)。 这是输出字段。
MQPMO 还可容纳分发列表所需的字段 (请参阅 分发列表 )。 如果要使用此工具,可使用 MQPMO V2 结构。 此结构包含以下字段:
RecsPresent
此字段包含分发列表中的队列数;即,存在的放置消息记录 (MQPMR) 和相应响应记录 (MQRR) 的数目。

输入的值可与 MQOPEN 提供的对象记录数相同。 但是,如果值小于执行 MQOPEN 调用时提供的对象记录数,或者如果未提供放置消息记录,那么未定义的队列的值取自消息描述符提供的缺省值。 此外,如果值大于提供的对象记录数,那么会忽略额外的放置消息记录。

建议执行以下其中一项操作:
  • 如果要接收来自目标的报告或回复,请输入 MQOR 结构中所显示的相同值,并使用包含 MsgId 字段的 MQPMR。 将这些 MsgId 字段初始化为零或指定 MQPMO_NEW_MSG_ID。

    已将消息放置到队列上时,队列管理器创建的 MsgId 值在 MQPMR 中将可用;可以使用这些值来识别与各个报告或回复关联的目标。

  • 如果不希望接收报告或回复,请选择以下项之一:
    1. 如果要立即识别失败的目标,那么可能仍要在 RecsPresent 字段中输入 MQOR 结构中显示的相同值,并提供 MQRR 以识别这些目标。 不要指定任何 MQPMR。
    2. 如果不希望识别失败的目标,请在 RecsPresent 字段中输入零,且不要提供 MQPMR 和 MQRR。
注: 如果使用 MQPUT1,那么响应记录指针数和响应记录偏移量必须为零。

有关放置消息记录 (MQPMR) 和响应记录 (MQRR) 的完整描述,请参阅 MQPMRMQRR

PutMsgRecFields
这指示每个放置消息记录 (MQPMR) 中存在哪些字段。 有关这些字段的列表,请参阅 使用 MQPMR 结构
PutMsgRecOffsetPutMsgRecPtr
指针 (通常在 C 中) 和偏移量 (通常在 COBOL 中) 用于寻址放置消息记录 (请参阅 使用 MQPMR 结构 以获取 MQPMR 结构的概述)。

使用 PutMsgRecPtr 字段指定指向第一个放置消息记录的指针,或者使用 PutMsgRecOffset 字段指定第一个放置消息记录的偏移量。 这是距离 MQPMO 开始的偏移量。 根据 PutMsgRecFields 字段,输入 PutMsgRecOffsetPutMsgRecPtr 的非空值。

ResponseRecOffset 和 ResponseRecPtr
您还可以使用指针和偏移量来处理响应记录 (请参阅 使用 MQRR 结构 以获取有关响应记录的更多信息)。

使用 ResponseRecPtr 字段指定指向第一个响应记录的指针,或者使用 ResponseRecOffset 字段指定第一个响应记录的偏移量。 这是距离 MQPMO 结构开始的偏移量。 输入 ResponseRecOffsetResponseRecPtr 的非空值。

注: 如果使用 MQPUT1 将消息放入分发列表,那么 ResponseRecPtr 必须为空或零, ResponseRecOffset 必须为零。
此外,MQPMO V3 结构还包含以下字段:
OriginalMsgHandle
对此字段的使用取决于 Action 字段的值。 如果要放置具有关联消息属性的新消息,请将此字段设置为先前创建的消息句柄,并将属性设置为启用。 如果要转发、回复或生成报告以响应先前检索的消息,那么此字段包含此消息的消息句柄。
NewMsgHandle
如果指定 NewMsgHandle,那么与句柄关联的任何属性将覆盖与 OriginalMsgHandle 关联的属性。 有关更多信息,请参阅 操作 (MQLONG)
操作
使用此字段指定将执行的放置操作的类型。 可能值及其含义如下所示:
MQACTP_NEW
这是与其他任何消息不相关的新消息。
MQACTP_FORWARD
先前检索了此消息,现在将转发此消息。
MQACTP_REPLY
此消息是对先前检索的消息的回复。
MQACTP_REPORT
此消息是由于先前检索到的消息生成的报告。
有关更多信息,请参阅 操作 (MQLONG)
PubLevel
如果此消息是发布消息,那么可设置此字段以确定哪些预订接收此消息。 仅 SubLevel 小于或等于此值的预订将接收此发布。 缺省值为 9(最高级别),表示具有任何 SubLevel 的预订都可接收此发布。

消息中的数据

在 MQPUT 调用的 Buffer 参数中提供包含数据的缓冲区的地址。 您可以在消息的数据中包含任何内容。 但是,消息中的数据量会影响处理这些消息的应用程序的性能。

数据的最大大小由以下内容确定:
  • 队列管理器的 MaxMsgLength 属性
  • 将在其上放置消息的队列的 MaxMsgLength 属性
  • IBM MQ 添加的任何消息头的大小 (包括死信头, MQDLH 和分发列表头, MQDH)

队列管理器的 MaxMsgLength 属性具有队列管理器可处理的消息的大小。 对于 V6 或更高版本的所有 IBM MQ 产品,缺省值为 100 MB。

要确定此属性的值,请针对队列管理器对象使用 MQINQ 调用。 对于较大的消息,可更改此值。

队列的 MaxMsgLength 属性确定可放置到队列上的消息的最大大小。 如果尝试放置大小大于此属性值的消息,那么 MQPUT 调用会失败。 如果要将消息放置到远程队列上,那么可成功放置的消息的最大大小由以下对象确定:远程队列、沿着目标路径放置消息的任何中间传输队列以及使用的通道的 MaxMsgLength 属性。

对于 MQPUT 操作,消息的大小必须小于或等于队列和队列管理器的 MaxMsgLength 属性。 这些属性的值是独立的,但建议您将队列的 MaxMsgLength 设置为小于或等于队列管理器的对应属性。

在以下情况下, IBM MQ 会向消息添加头信息:
  • 将消息放入远程队列时, IBM MQ 会向消息添加传输头结构 (MQXQH)。 此结构包含目标队列的名称及其拥有的队列管理器的名称。
  • 如果 IBM MQ 无法将消息传递到远程队列,那么它会尝试将消息放在死信 (undelivered-message) 队列上。 它会将 MQDLH 结构添加到消息。 此结构包含目标队列的名称以及将消息放置到死信队列上的原因。
  • 如果要将消息发送到多个目标队列,那么 IBM MQ 会向消息添加 MQDH 头。 这描述了消息中存在的数据,消息属于分发列表,在传输队列上。 为最大消息长度选择最优值时,考虑此情况。
  • 如果消息是段或组中的消息,那么 IBM MQ 可能会添加 MQMDE。

这些结构在 MQDHMQMDE中进行了描述。

如果消息超出这些队列允许的最大大小,那么添加这些头意味着,由于消息目前太大会导致放置操作失败。 要降低放置操作失败的可能性,请执行以下操作:
  • 使消息大小小于传输队列和死信队列的 MaxMsgLength 属性。 至少允许 MQ_MSG_HEADER_LENGTH 常量的值(对于较大分发列表,还需允许其他值)。
  • 确保死信队列的 MaxMsgLength 属性设置为与拥有死信队列的队列管理器的 MaxMsgLength 相同。

队列管理器的属性中描述了队列管理器和消息排队常量的属性。

[z/OS]有关如何在分布式排队环境中处理未传递的消息的信息,请参阅 未传递/未处理的消息

放置消息:使用消息句柄

MQPMO 结构中提供了两个消息句柄:OriginalMsgHandleNewMsgHandle。 这些消息句柄之间的关系由 MQPMO Action 字段的值定义。

有关完整详细信息,请参阅 操作 (MQLONG)。 消息句柄对于放置消息不是必要的。 其目的是将属性与消息关联,因此,仅当使用消息属性时,才需要消息句柄。