Conditions for a trigger event
The queue manager creates a trigger message when the conditions detailed in this topic are satisfied.
References to shared queues in this topic mean shared queues in a queue sharing group, only available on IBM MQ for z/OSĀ®.
The following conditions cause the queue manager to create a trigger message:- A message is put on a queue.
- The message has a priority greater than or equal to the threshold trigger priority of the queue. This priority is set in the TriggerMsgPriority local queue attribute; if it is set to zero, any message qualifies.
- The number of messages on the queue with priority greater than or equal to TriggerMsgPriority was previously, depending on TriggerType:
- Zero (for trigger type MQTT_FIRST)
- Any number (for trigger type MQTT_EVERY)
- TriggerDepth minus 1 (for trigger type MQTT_DEPTH)
- For non-shared local queues, the queue manager counts both committed and uncommitted messages when it assesses whether the conditions for a trigger event exist. Consequently an application might be started when there are no messages for it to retrieve because the messages on the queue have not been committed. In this situation, consider using the wait option with a suitable WaitInterval, so that the application waits for its messages to arrive.
- For local shared queues, the queue manager counts committed messages only.
- For triggering of type FIRST or DEPTH, no program has the application queue open for removing messages (that is, the OpenInputCount local queue attribute is zero).
Note:
- For shared queues, special conditions apply when multiple queue managers have trigger monitors running against a queue. In this situation, if one or more queue managers have the queue open for input shared, the trigger criteria on the other queue managers are treated as TriggerType MQTT_FIRST and TriggerMsgPriority zero. When all the queue managers close the queue for input, the trigger conditions revert to those conditions specified in the queue definition.
An example scenario affected by this condition is multiple queue managers QM1, QM2, and QM3 with a trigger monitor running for an application queue A. A message arrives on A satisfying the conditions for triggering, and a trigger message is generated on the initiation queue. The trigger monitor on QM1 gets the trigger message and triggers an application. The triggered application opens the application queue for shared input. From this point on the trigger conditions for application queue A are evaluated as TriggerType MQTT_FIRST, and TriggerMsgPriority zero on queue managers QM2 and QM3, until QM1 closes the application queue.
- For shared queues, this condition is applied for each queue manager. That is, a queue manager's OpenInputCount for a queue must be zero for a trigger message to be generated for the queue by that queue manager. However, if any queue manager in the queue sharing group has the queue open using the MQOO_INPUT_EXCLUSIVE option, no trigger message is generated for that queue by any of the queue managers in the queue sharing group.
The change in how the trigger conditions are evaluated occurs when the triggered application opens the queue for input. In scenarios where there is only one trigger monitor running, other applications can have the same effect because they similarly open the application queue for input. It does not matter whether the application queue was opened by an application that is started by a trigger monitor, or by some other application; it is the fact that the queue is open for input on another queue manager that causes the change in trigger criteria.
- For shared queues, special conditions apply when multiple queue managers have trigger monitors running against a queue. In this situation, if one or more queue managers have the queue open for input shared, the trigger criteria on the other queue managers are treated as TriggerType MQTT_FIRST and TriggerMsgPriority zero. When all the queue managers close the queue for input, the trigger conditions revert to those conditions specified in the queue definition.
- On IBM MQ for z/OS, if the application queue is one with a Usage attribute of MQUS_NORMAL, get requests for it are not inhibited (that is, the InhibitGet queue attribute is MQQA_GET_ALLOWED). Also, if the triggered application queue is one with a Usage attribute of MQUS_XMITQ, get requests for it are not inhibited.
- Either:
- The ProcessName local queue attribute for the queue is not blank, and the process definition object identified by that attribute has been created, or
- The ProcessName local queue attribute for the queue is all blank, but the queue is a transmission queue. As the process definition is optional, the TriggerData attribute might also contain the name of the channel to be started. In this case, the trigger message contains attributes with the following values:
- QName: queue name
- ProcessName: blanks
- TriggerData: trigger data
- ApplType: MQAT_UNKNOWN
- ApplId: blanks
- EnvData: blanks
- UserData: blanks
- An initiation queue has been created, and has been specified in the InitiationQName local queue attribute. Also:
- Get requests are not inhibited for the initiation queue (that is, the value of the InhibitGet queue attribute is MQQA_GET_ALLOWED).
- Put requests must not be inhibited for the initiation queue (that is, the value of the InhibitPut queue attribute must be MQQA_PUT_ALLOWED).
- The value of the Usage attribute of the initiation queue must be MQUS_NORMAL.
- In environments where dynamic queues are supported, the initiation queue must not be a dynamic queue that has been marked as logically deleted.
- A trigger monitor currently has the initiation queue open for removing messages (that is, the OpenInputCount local queue attribute is greater than zero).
- The trigger control (TriggerControl local queue attribute) for the application queue is set to MQTC_ON. To do this, set the trigger attribute when you define your queue, or use the ALTER QLOCAL command.
- The trigger type (TriggerType local queue attribute) is not MQTT_NONE.
If all the required conditions are met, and the message that caused the trigger condition is put as part of a unit of work, the trigger message does not become available for retrieval by the trigger monitor application until the unit of work completes, whether the unit of work is committed or, for trigger type MQTT_FIRST or MQTT_DEPTH, backed out.
- A suitable message is placed on the queue, for a TriggerType of MQTT_FIRST or MQTT_DEPTH, and the queue:
- Was not previously empty (MQTT_FIRST), or
- Had TriggerDepth or more messages (MQTT_DEPTH)
This is to allow for a queue server that ends before processing all the messages on the queue. The purpose of the trigger interval is to reduce the number of duplicate trigger messages that are generated.
Note: If you stop and restart the queue manager, the TriggerInterval timer is reset. There is a small window during which it is possible to produce two trigger messages. The window exists when the trigger attribute of the queue is set to enabled at the same time as a message arrives and the queue was not previously empty (MQTT_FIRST) or had TriggerDepth or more messages (MQTT_DEPTH). - The only application serving a queue issues an MQCLOSE call, for a TriggerType of MQTT_FIRST or MQTT_DEPTH, and there is at least:
- One (MQTT_FIRST), or
- TriggerDepth (MQTT_DEPTH)
- If the program serving the application queue does not retrieve all the messages, this can cause a closed loop. Each time that the program closes the queue, the queue manager creates another trigger message that causes the trigger monitor to start the server program again.
- If the program serving the application queue backs out its get request (or if the program abends) before it closes the queue, the same happens. However, if the program closes the queue before backing out the get request, and the queue is otherwise empty, no trigger message is created.
- To prevent such a loop occurring, use the BackoutCount field of MQMD to detect messages that are repeatedly backed out. For more information, see Messages that are backed out.
- The following conditions are satisfied using MQSET or a command:
-
- TriggerControl is changed to MQTC_ON, or
- TriggerControl is already MQTC_ON and the value of either TriggerType, TriggerMsgPriority, or TriggerDepth (if relevant) is changed,
- One (MQTT_FIRST or MQTT_EVERY), or
- TriggerDepth (MQTT_DEPTH)
This is to allow for an application or operator changing the triggering criteria, when the conditions for a trigger to occur are already satisfied.
- The value of the InhibitPut queue attribute of an initiation queue changes from MQQA_PUT_INHIBITED to MQQA_PUT_ALLOWED, and there is at least:
- One (MQTT_FIRST or MQTT_EVERY), or
- TriggerDepth (MQTT_DEPTH)
This is to allow for trigger messages not being generated because of the MQQA_PUT_INHIBITED condition on the initiation queue, but this condition now having been changed.
- The value of the InhibitGet queue attribute of an application queue changes from MQQA_GET_INHIBITED to MQQA_GET_ALLOWED, and there is at least:
- One (MQTT_FIRST or MQTT_EVERY), or
- TriggerDepth (MQTT_DEPTH)
This allows applications to be triggered only when they can retrieve messages from the application queue.
- A trigger-monitor application issues an MQOPEN call for input from an initiation queue, and there is at least:
- One (MQTT_FIRST or MQTT_EVERY), or
- TriggerDepth (MQTT_DEPTH)
This is to allow for messages arriving on queues while the trigger monitor is not running, and for the queue manager restarting and trigger messages (which are nonpersistent) being lost.
-
- MSGDLVSQ is set correctly. If you set MSGDLVSQ=FIFO, messages are delivered to the queue in a First In First Out basis. The priority of the message is ignored and the default priority of the queue is assigned to the message. If TriggerMsgPriority is set to a higher value than the default priority of the queue, no messages are triggered. If TriggerMsgPriority is set equal to or lower than the default priority of the queue, triggering occurs for type FIRST, EVERY, and DEPTH. For information about these types, see the description of the TriggerType field under Controlling trigger events.
If you set MSGDLVSQ=PRIORITY and the message priority is equal to or greater than the TriggerMsgPriority field, messages only count towards a trigger event. In this case, triggering occurs for type FIRST, EVERY, and DEPTH. As an example, if you put 100 messages of lower priority than the TriggerMsgPriority, the effective queue depth for triggering purposes is still zero. If you then put another message on the queue, but this time the priority is greater than or equal to the TriggerMsgPriority, the effective queue depth increases from zero to one and the condition for TriggerType FIRST is satisfied.
- From step 12 (where trigger messages are generated as a result of some event other than a message arriving on the application queue), the trigger message is not put as part of a unit of work. Also, if the TriggerType is MQTT_EVERY, and if there are one or more messages on the application queue, only one trigger message is generated.
- If IBM MQ segments a message during MQPUT, a trigger event will not be processed until all the segments have been successfully placed on the queue. However, once message segments are on the queue, IBM MQ treats them as individual messages for triggering purposes. For example, a single logical message split into three pieces causes only one trigger event to be processed when it is first MQPUT and segmented. However, each of the three segments causes their own trigger events to be processed as they are moved through the IBM MQ network.