WebSphere MQ Application Programming Guide
WebSphere MQ Application Programming Guide
SC34-6939-00
WebSphere MQ
SC34-6939-00
Note
Before using this information and the product it supports, be sure to read the general information under notices at the back
of this book.
Contents v
vi WebSphere MQ: Application Programming Guide
Figures
1. Message queuing compared with traditional 30. Dynamic linking using COBOL in the IMS
communication . . . . . . . . . . . . 5 environment . . . . . . . . . . . . 379
2. Representation of a message . . . . . . . 16 31. Dynamic linking using assembler language in
3. Selection using MQSUB call . . . . . . . 33 the batch environment . . . . . . . . 380
4. Selection using MQOPEN call . . . . . . 34 32. Dynamic linking using assembler language in
5. Standard Message Driven application the CICS environment . . . . . . . . 380
consuming from two queues . . . . . . . 42 33. Dynamic linking using assembler language in
6. Single Threaded Message Driven application the IMS environment . . . . . . . . . 380
consuming from two queues . . . . . . . 43 34. Dynamic linking using C language in the
7. Group of logical messages . . . . . . . 43 batch environment . . . . . . . . . . 380
8. Segmented messages . . . . . . . . . 44 35. Dynamic linking using C language in the
9. How distribution lists work . . . . . . . 120 CICS environment . . . . . . . . . . 380
10. Opening a distribution list in C . . . . . 122 36. Dynamic linking using C language in the IMS
11. Opening a distribution list in COBOL 122 environment . . . . . . . . . . . . 381
12. Putting a message to a distribution list in C 124 37. Dynamic linking using PL/I in the batch
13. Putting a message to a distribution list in environment . . . . . . . . . . . . 381
COBOL . . . . . . . . . . . . . 124 38. Dynamic linking using PL/I in the IMS
14. Logical order on a queue . . . . . . . 132 environment . . . . . . . . . . . . 381
15. Physical order on a queue . . . . . . . 133 39. Running the Reference Message samples 412
16. Skipping backout using 40. Request and Inquire samples using triggering 420
MQGMO_MARK_SKIP_BACKOUT . . . . 153 41. Sample i5/OS Client/Server (Echo) program
17. Sample JCL used to invoke the CSQUCVX flowchart . . . . . . . . . . . . . 423
utility . . . . . . . . . . . . . . 167 42. The database coordination samples . . . . 431
18. Flow of application and trigger messages 197 43. Example of ubbstxcn.cfg file for WebSphere
19. Relationship of queues within triggering 199 MQ for Windows . . . . . . . . . . 444
20. Setting of key fields for many CICS user 44. Sample TUXEDO makefile for WebSphere
programs in a unit of work viewed from the MQ for Windows . . . . . . . . . . 445
perspective of the bridge . . . . . . . . 292 45. Example of ubbstxcn.cfg file for WebSphere
21. Setting of key fields: WebSphere MQ - MQ for Windows . . . . . . . . . . 446
pseudo-conversational 3270 transaction 46. Sample TUXEDO makefile for WebSphere
viewed from the perspective of the bridge MQ for Windows . . . . . . . . . . 447
prior to CICS TS 2.2 . . . . . . . . . 315 47. How TUXEDO samples work together 448
22. Setting of key fields: WebSphere MQ - 48. Example of a report from the Print Message
conversational 3270 transaction viewed from sample application . . . . . . . . . . 474
the perspective of the bridge . . . . . . 317 49. Programs and panels for the TSO versions of
23. User program abends (only program in the the Mail Manager . . . . . . . . . . 481
unit of work) . . . . . . . . . . . 319 50. Programs and panels for the CICS version of
24. Fragments of JCL to link-edit the object the Mail Manager . . . . . . . . . . 482
module in the batch environment, using 51. Example of a panel showing a list of waiting
single-phase commit . . . . . . . . . 374 messages . . . . . . . . . . . . . 483
25. Fragments of JCL to link-edit the object 52. Example of a panel showing the contents of a
module in the batch environment, using message . . . . . . . . . . . . . 484
two-phase commit . . . . . . . . . . 374 53. Immediate Inquiry panel for the Credit Check
26. Fragments of JCL to link-edit the object sample application . . . . . . . . . . 487
module in the CICS environment . . . . . 375 54. Programs and queues for the Credit Check
27. Fragments of JCL to link-edit the object sample application (COBOL programs only) . 489
module in the IMS environment . . . . . 376 55. Initial screen for Message Handler sample 500
28. Dynamic linking using COBOL in the batch 56. Message list screen for Message Handler
environment . . . . . . . . . . . . 379 sample . . . . . . . . . . . . . . 500
29. Dynamic linking using COBOL in the CICS 57. Chosen message is displayed . . . . . . 501
environment . . . . . . . . . . . . 379
Applications designed and written using this interface are known as message
queuing applications, because they use the messaging and queuing style:
This chapter introduces messaging and queuing concepts, under these headings:
v “What is message queuing?”
v “What is a message?” on page 2
v “What is a message queue?” on page 2
v “What is a queue manager?” on page 3
v “What is a cluster?” on page 3
v “What is a WebSphere MQ client?” on page 4
v “Main features of message queuing” on page 4
v “Benefits of message queuing to the application designer and developer” on
page 7
v “What can you do with WebSphere MQ products?” on page 7
Even so, many complex business transactions are processed today without
queuing. In a large network, the system might be maintaining many thousands of
connections in a ready-to-use state. If one part of the system suffers a problem,
many parts of the system become unusable.
You can think of message queuing as being electronic mail for programs. In a
message queuing environment, each program from the set that makes up an
application suite is designed to perform a well-defined, self-contained function in
response to a specific request. To communicate with another program, a program
What is a message?
In message queuing, a message is a collection of data sent by one program and
intended for another program.
See “Types of message” on page 17 for more information about these message
types.
Message descriptor
A WebSphere MQ message consists of control information and application data.
References are made to them in this book when dealing with report messages and
you will need to consider them when designing your application. See WebSphere
MQ Intercommunications for more information.
Programs access queues only through the external services of the queue manager.
They can open a queue, put messages on it, get messages from it, and close the
queue. They can also set, and inquire about, the attributes of queues.
Many different applications can use the queue manager’s services at the same time
and these applications can be entirely unrelated. For a program to use the services
of a queue manager, it must establish a connection to that queue manager.
For applications to send messages to applications that are connected to other queue
managers, the queue managers must be able to communicate among themselves.
WebSphere MQ implements a store-and-forward protocol to ensure the safe delivery
of messages between such applications.
What is a cluster?
A cluster is a network of queue managers that are logically associated in some way.
Clustering is available to queue managers on all WebSphere MQ V7.0 platforms.
If you group queue managers in a cluster, the queue managers can make the
queues that they host available to every other queue manager in the cluster. Then,
assuming that you have the necessary network infrastructure in place, any queue
manager can send a message to any other queue manager in the same cluster
without the need for explicit channel definitions, remote queue definitions, or
transmission queues.
There are two different reasons for using clusters: to reduce system administration
and to improve availability and workload balancing.
A shared queue is a type of local queue whose messages can be accessed by one or
more queue managers that are in a sysplex. (This is not the same as a queue being
shared by more than one application, using the same queue manager.)
The queue managers that can access the same set of shared queues form a group
called a queue-sharing group (QSG). They communicate with each other by means of
a coupling facility (CF) that stores the shared queues. See the WebSphere MQ for
z/OS Concepts and Planning Guide for a full discussion of queue-sharing groups.
For full details on how to install and use WebSphere MQ client components, see
WebSphere MQ Clients.
What is publish/subscribe?
Publish/subscribe messaging allows you to decouple the provider of information
from the consumers of that information. The sending application (publisher) and
receiving application (subscriber) do not need to know anything about each other
for the information to be sent and received.
Program A Program B
Networking software
Program A Program B
WebSphere MQ
comms code
(Queue Manager)
Networking software
Similarly, the WebSphere MQ client can, without change, function with additional
types of server. See WebSphere MQ Clients for more information.
Designers can reduce the cost of their applications because development is faster,
fewer developers are needed, and demands on programming skill are lower than
those for applications that do not use message queuing.
Each environment within z/OS has its own characteristics, advantages, and
disadvantages. The advantage of WebSphere MQ for z/OS is that applications are
not tied to any one environment, but can be distributed to take advantage of the
benefits of each environment. For example, you can develop end-user interfaces
using TSO or CICS, you can run processing-intensive modules in z/OS batch, and
you can run database applications in IMS or CICS. In all cases, the various parts of
the application can communicate using messages and queues.
The differences between the supported environments, and their limitations, are
discussed further in “Using and writing applications on WebSphere MQ for z/OS”
on page 269.
These subjects are discussed in greater detail in the remaining chapters of this
book.
The remainder of this chapter introduces the features and techniques that
WebSphere MQ provides to help you answer questions like these.
These objects, and queue-sharing groups (which are only supported on WebSphere
MQ for z/OS and which are not strictly objects), are discussed in “WebSphere MQ
objects” on page 48.
With the exception of dynamic queues, these objects must be defined to the queue
manager before you can work with them.
You can also display or alter the attributes of objects, or delete the objects.
Alternatively, for sequences of WebSphere MQ for z/OS commands that you use
regularly, you can write administration programs that create messages containing
commands and that put these messages on the system-command input queue. The
queue manager processes the messages on this queue in the same way that it
processes commands entered from the command line or from the operations and
control panels. This technique is described in the z/OS System Administration Guide,
and demonstrated in the Mail Manager sample application delivered with
WebSphere MQ for z/OS. For a description of this sample, see “Sample programs
for WebSphere MQ for z/OS” on page 452.
For sequences of WebSphere MQ for i5/OS commands that you use regularly you
can write CL programs.
You create a message when you use an MQI call to put the message on a queue.
As input to the call, you supply some control information in a message descriptor
(MQMD) and the data that you want to send to another program. But at the
design stage, you need to consider the following questions, because they affect the
way that you create your messages:
What type of message should I use?
Are you designing a simple application in which you can send a message,
then take no further action? Or are you asking for a reply to a question? If
WebSphere MQ techniques
For a simple WebSphere MQ application, you need to decide which WebSphere
MQ objects to use in your application, and which types of message you want to
use. For a more advanced application, you might want to use some of the
techniques introduced in the following sections.
Correlating replies
In WebSphere MQ applications, when a program receives a message that asks it to
do some work, the program usually sends one or more reply messages to the
requester.
To help the requester to associate these replies with its original request, an
application can set a correlation identifier field in the descriptor of each message.
Programs then copy the message identifier of the request message into the
correlation identifier field of their reply messages.
When you create a message, you can specify an option that requests that the queue
manager associates default context information with your message.
For more information on using and setting context information, see “Message
context” on page 46.
You can set trigger conditions on a queue so that a program starts to process that
queue:
v Every time that a message arrives on the queue
v When the first message arrives on the queue
v When the number of messages on the queue reaches a predefined number
On platforms other than z/OS, WebSphere MQ can define service objects to start
WebSphere MQ programs when the queue manager starts; see WebSphere MQ
Migration Information.
Within a cluster, a message can be routed to any queue manager that hosts an
instance of the appropriate queue. Therefore, the logic of applications with
message affinities can be upset.
For example, you might have two applications that rely on a series of messages
flowing between them in the form of questions and answers. It might be important
that all the questions are sent to the same queue manager and that all the answers
are sent back to the other queue manager. In this situation, it is important that the
workload management routine does not send the messages to any queue manager
that just happens to host an instance of the appropriate queue.
Where possible, remove the affinities. Removing message affinities improves the
availability and scalability of applications.
Application programming
WebSphere MQ supports the IBM Message Queue Interface (MQI). The MQI
includes a set of calls with which you can send and receive messages, and
manipulate WebSphere MQ objects.
Call interface
Use MQI calls to:
v Connect programs to, and disconnect programs from, a queue manager.
v Open and close objects (such as queues, queue managers, namelists, and
processes).
v Put messages on queues and topics.
v Receive messages from a queue, or browse them (leaving them on the queue).
v Subscribe to topics.
v Inquire about the attributes (or properties) of WebSphere MQ objects, and set
some of the attributes of queues.
v Commit and back out changes made within a unit of work, in environments
where there is no natural syncpoint support, for example, UNIX systems.
The MQI provides structures (groups of fields) with which you supply input to,
and get output from, the calls. It also provides a large set of named constants to
help you supply options in the parameters of the calls. The definitions of the calls,
structures, and named constants are supplied in data definition files for each of the
supported programming languages. Also, default values are set within the MQI
calls.
Programming platforms
For details of supported programming platforms, refer to the product
announcements at
http://www.ibm.com/software/integration/wmq/requirements
If you are using C, code in ANSI standard C. Use a standard C library function
rather than an equivalent platform-specific function even if the platform-specific
function is faster or more efficient. The exception is when efficiency in the code is
paramount, when you should code for both situations using #ifdef. For example:
#ifdef _AIX
AIX specific code
#else
generic code
#endif
Keep portable code in separate source files from the platform-specific code, and
use a simple naming convention to split the categories.
When testing CICS applications with WebSphere MQ for z/OS, you can use the
CICS Execution Diagnostic Facility (CEDF). CEDF traps the entry and exit of every
MQI call as well as calls to all CICS services. Also, in the CICS environment, you
can write an API-crossing exit program to provide diagnostic information before
and after every MQI call. For information on how to do this, see “Using and
writing applications on WebSphere MQ for z/OS” on page 269.
When testing i5/OS applications, you can use the standard Debugger. To start this,
use the STRDBG command.
WebSphere MQ messages
WebSphere MQ messages are made up of two parts:
v Message properties
v Application data
Figure 2 represents a message and shows how it is logically divided into message
properties and application data.
Message description
(MQMD)
Make your messages slightly shorter than the value of the MaxMsgLength attribute
in some circumstances. See “The data in your message” on page 113 for more
information.
You create a message when you use the MQPUT or MQPUT1 MQI calls. As input
to these calls, you supply the control information (such as the priority of the
message and the name of a reply queue) and your data , and the call then puts the
message on a queue. See the WebSphere MQ Application Programming Reference for
more information on these calls.
Message descriptor
You can access message control information using the MQMD structure, which
defines the message descriptor.
For a full description of the MQMD structure, see the WebSphere MQ Application
Programming Reference.
See “Message context” on page 46 for a description of how to use the fields within
the MQMD that contain information about the origin of the message.
There are different versions of the message descriptor. Additional information for
grouping and segmenting messages (see “Message groups” on page 43) is
provided in Version 2 of the message descriptor (or the MQMDE). This is the same
as the Version 1 message descriptor but has additional fields. These are described
in the WebSphere MQ Application Programming Reference.
Types of message
There are four types of message defined by WebSphere MQ:
v Datagram
Applications can use the first three types of messages to pass information between
themselves. The fourth type, report, is for applications and queue managers to use
to report information about events such as the occurrence of an error.
Each type of message is identified by an MQMT_* value. You can also define your
own types of message. For the range of values you can use, see the description of
the MsgType field in the WebSphere MQ Application Programming Reference.
Datagrams
Use a datagram when you do not require a reply from the application that receives
the message (that is, gets the message from the queue).
An example of an application that could use datagrams is one that displays flight
information in an airport lounge. A message could contain the data for a whole
screen of flight information. Such an application is unlikely to request an
acknowledgement for a message because it probably does not matter if a message
is not delivered. The application sends an update message after a short period of
time.
Request messages
Use a request message when you want a reply from the application that receives the
message.
An example of an application that could use request messages is one that displays
the balance of a checking account. The request message could contain the number
of the account, and the reply message would contain the account balance.
If you want to link your reply message with your request message, there are two
options:
v Make the application that handles the request message responsible for ensuring
that it puts information into the reply message that relates to the request
message.
v Use the report field in the message descriptor of your request message to specify
the content of the MsgId and CorrelId fields of the reply message:
– You can request that either the MsgId or the CorrelId of the original message
is to be copied into the CorrelId field of the reply message (the default action
is to copy MsgId).
– You can request that either a new MsgId is generated for the reply message, or
that the MsgId of the original message is to be copied into the MsgId field of
the reply message (the default action is to generate a new message identifier).
Reply messages
Use a reply message when you reply to another message.
When you create a reply message, respect any options that were set in the message
descriptor of the message to which you are replying. Report options specify the
content of the message identifier (MsgId) and correlation identifier (CorrelId) fields.
These fields allow the application that receives the reply to correlate the reply with
its original request.
Report messages can be generated at any time, and might arrive on a queue when
your application is not expecting them.
You can request more than one type of report message when you put a message on
a queue. If you select the delivery confirmation report message and the exception
report message options, in the event that the message fails to be delivered, you
receive an exception report message. However, if you select only the delivery
confirmation report message option and the message fails to be delivered, you do
not get an exception report message.
The report messages that you request, when the criteria for generating a particular
message are met, are the only ones that you receive.
Note: A benefit of this is that you can reduce the number of messages going to the
dead-letter queue. However, it does mean that your application, unless it sends
only datagram messages, has to deal with returned messages. When an exception
report message is generated, it inherits the persistence of the original message.
If a report message cannot be delivered (if the queue is full, for instance), the
report message is placed on the dead-letter queue.
If you want to receive a report message, specify the name of your reply-to queue
in the ReplyToQ field; otherwise the MQPUT or MQPUT1 of your original message
fails with MQRC_MISSING_REPLY_TO_Q.
You can use other report options in the message descriptor (MQMD) of a message
to specify the content of the MsgId and CorrelId fields of any report messages that
are created for the message:
v You can request that either the MsgId or the CorrelId of the original message is
to be copied into the CorrelId field of the report message. The default action is
to copy the message identifier. Use MQRO_COPY_MSG_ID_TO_CORRELID
because it enables the sender of a message to correlate the reply or report
message with the original message. The correlation identifier of the reply or
report message will be identical to the message identifier of the original
message.
v You can request that either a new MsgId is generated for the report message, or
that the MsgId of the original message is to be copied into the MsgId field of the
report message. The default action is to generate a new message identifier. Use
MQRO_NEW_MSG_ID because it ensures that each message in the system has a
different message identifier, and can be distinguished unambiguously from all
other messages in the system.
v Specialized applications might need to use MQRO_PASS_MSG_ID or
MQRO_PASS_CORREL_ID. However, you need to design the application that
reads the messages from the queue to ensure that it works correctly when, for
example, the queue contains multiple messages with the same message
identifier.
Server applications must check the settings of these flags in the request message,
and set the MsgId and CorrelId fields in the reply or report message
appropriately.
Applications that act as intermediaries between a requester application and a
server application should not need to check the settings of these flags. This is
because these applications usually need to forward the message to the server
application with the MsgId, CorrelId, and Report fields unchanged. This allows
the server application to copy the MsgId from the original message in the
CorrelId field of the reply message.
When generating a report about a message, server applications must test to see if
any of these options have been set.
For more information on how to use report messages, see the description of the
Report field in the WebSphere MQ Application Programming Guide.
To indicate the nature of the report, queue managers use a range of feedback
codes. They put these codes in the Feedback field of the message descriptor of a
For more information on feedback and reason codes, see the description of the
Feedback field in the WebSphere MQ Application Programming Guide.
An example of a program that could use a feedback code is one that monitors the
workloads of other programs serving a queue. If there is more than one instance of
a program serving a queue, and the number of messages arriving on the queue no
longer justifies this, such a program can send a report message (with the feedback
code MQFB_QUIT) to one of the serving programs to indicate that the program
should terminate its activity. (A monitoring program could use the MQINQ call to
find out how many programs are serving a queue.)
If you segment your messages or allow the queue manager to do so, there is only
one case in which you can expect to receive a single report for the entire message.
This is when you have requested only COD reports, and you have specified
MQGMO_COMPLETE_MSG on the getting application.
In other cases your application must be prepared to deal with several reports;
usually one for each segment.
Note: If you segment your messages, and you need only the first 100 bytes of the
original message data to be returned, change the setting of the report options to
ask for reports with no data for segments that have an offset of 100 or more. If you
do not do this, and you leave the setting so that each segment requests 100 bytes
of data, and you retrieve the report messages with a single MQGET specifying
MQGMO_COMPLETE_MSG, the reports assemble into a large message containing
100 bytes of read data at each appropriate offset. If this happens, you need a large
buffer or you need to specify MQGMO_ACCEPT_TRUNCATED_MSG.
If your application generates reports, always copy the WebSphere MQ headers that
are present at the start of the original message data to the report message data.
Then add none, 100 bytes, or all of the original message data (or whatever other
amount you would usually include) to the report message data.
You can recognize the WebSphere MQ headers that must be copied by looking at
the successive Format names, starting with the MQMD and continuing through
any headers present. The following Format names indicate these WebSphere MQ
headers:
v MQMDE
v MQDLH
v MQXQH
The Format name occurs at specific positions for MQDLH and MQXQH, but for the
other WebSphere MQ headers it occurs at the same position. The length of the
header is contained in a field that also occurs at the same position for MQMDE,
MQIMS, and all MQH* headers.
If you are using a Version 1 MQMD, and you are reporting on a segment, or a
message in a group, or a message for which segmentation is allowed, the report
data must start with an MQMDE. Set the OriginalLength field to the length of the
original message data excluding the lengths of any WebSphere MQ headers that
you find.
Retrieval of reports:
If you ask for COA or COD reports, you can ask for them to be reassembled for
you with MQGMO_COMPLETE_MSG.
You can use this technique even if there are several different report types present
on the queue (for example, both COA and COD), because an MQGET with
MQGMO_COMPLETE_MSG reassembles report messages only if they have the
same Feedback code. However, you cannot usually use this technique for exception
reports, because, in general, these have different Feedback codes.
You can use this technique to get a positive indication that the entire message has
arrived. However, in most circumstances you need to cater for the possibility that
some segments arrive while others might generate an exception (or expiry, if you
have allowed this). You cannot use MQGMO_COMPLETE_MSG in this case,
because, in general, you might get different Feedback codes for different segments
and, as noted above, you might get more than one report for a given segment. You
can, however, use MQGMO_ALL_SEGMENTS_AVAILABLE.
To allow for this you might need to retrieve reports as they arrive, and build up a
picture in your application of what happened to the original message. You can use
the GroupId field in the report message to correlate reports with the GroupId of the
original message, and the Feedback field to identify the type of each report
message. The way in which you do this depends on your application requirements.
However, if a segment of a message passes through a queue manager that does not
support segmentation, if a report is generated there, the MQMDE structure in the
original message is treated purely as data. It is not therefore included in the report
data if zero bytes of the original data have been requested. Without the MQMDE,
the report message might not be useful.
Request at least 100 bytes of data in reports if there is a possibility that the
message might travel through a back-level queue manager.
The CodedCharSetId attribute of the queue manager object defines this character
set. Control information must be in this character set because, when applications
pass messages from one queue manager to another, message channel agents that
transmit the messages use the value of this attribute to determine what data
conversion to perform.
The conversion is performed at the sending queue manager for certain built-in
formats and for user-defined formats if a suitable user exit is supplied.
Built-in formats:
These include:
v Messages that are all characters (using the format name MQFMT_STRING)
v WebSphere MQ defined messages, for example Programmable Command
Formats
WebSphere MQ uses Programmable Command Format messages for
administration messages and events (the format name used is MQFMT_ADMIN
in this case). You can use the same format (using the format name
MQFMT_PCF) for your own messages, and take advantage of the built-in data
conversion.
The queue manager built-in formats all have names beginning with MQFMT. They
are listed and described in the WebSphere MQ Application Programming Reference
under the Format field of the Message descriptor (MQMD).
Application-defined formats:
Application message data can be converted by the receiving queue manager for
both built-in and user-defined formats.
WebSphere MQ products support the coded character sets that are provided by the
underlying operating system.
When you create a queue manager, the queue manager coded character set ID
(CCSID) used is based on that of the underlying environment. If this is a mixed
code page, WebSphere MQ uses the SBCS part of the mixed code page as the
queue manager CCSID.
For general data conversion, if the underlying operating system supports DBCS
code pages, WebSphere MQ can use it.
See the documentation for your operating system for details of the coded character
sets that it supports.
You need to consider application data conversion, format names, and user exits
when writing applications that span multiple platforms. For details of the MQGET
Chapter 1. Designing applications that use WebSphere MQ 25
call, the Convert characters call, the MQGMO_CONVERT option, and the built-in
formats, see the WebSphere MQ Application Programming Reference. See “Writing
data-conversion exits” on page 163 for information about invoking and writing
data-conversion exits.
Message priorities
You set the priority of a message (in the Priority field of the MQMD structure)
when you put the message on a queue. You can set a numeric value for the
priority, or you can let the message take the default priority of the queue.
The DefPriority attribute of a queue sets the default priority value for messages
being put on that queue. This value is set when the queue is created, but it can be
changed afterwards. Alias queues, and local definitions of remote queues, can have
different default priorities from the base queues to which they resolve. If there is
more than one queue definition in the resolution path (see “Name resolution” on
page 101), the default priority is taken from the value (at the time of the put
operation) of the DefPriority attribute of the queue specified in the open
command.
The value of the MaxPriority attribute of the queue manager is the maximum
priority that you can assign to a message processed by that queue manager. You
cannot change the value of this attribute. In WebSphere MQ, the attribute has the
value 9; you can create messages having priorities between 0 (the lowest) and 9
(the highest).
Message properties
Use message properties to allow an application to select messages to process, or to
retrieve information about a message without accessing MQMD or MQRFH2
headers. They also facilitate communication between Websphere MQ and JMS
applications.
If the size of the properties exceeds the maximum properties length, the message is
rejected with MQRC_PROPERTIES_TOO_BIG. Because the size of the properties is
dependent on its representation, you should set the maximum properties length at
a gross level.
On an MQGET call, properties of the message do not count towards the length of
the message as far as the queue and the queue manager are concerned. However,
because the properties are counted separately it is possible that the buffer returned
by an MQGET call is larger than the value of the MaxMsgLength attribute.
Do not have your applications query the value of MaxMsgLength and then allocate
a buffer of this size before calling MQGET; instead, allocate a buffer you consider
large enough. If the MQGET fails, allocate a buffer guided by the size of the
DataLength parameter.
The DataLength parameter of the MQGET call now returns the length in bytes of
the application data and any properties returned in the buffer you have provided,
if a message handle is not specified in the MQGMO structure.
The Buffer parameter of the MQPUT call now contains the application message
data to be sent and any properties represented in the message data.
When flowing to a queue manager that is prior to Version 7.0 of the product,
properties of the message, except those in the message descriptor, count towards
the length of the message. Therefore, you should either raise the value of the
MaxMsgLength attribute of channels going to a system prior to Version 7.0 as
necessary, to compensate for the fact that more data might be sent for each
message. Alternatively, you can lower the queue or queue manager MaxMsgLength,
so that the overall level of data being sent around the system remains the same.
There is a length limit of 100 MB for message properties, excluding the message
descriptor or extension for each message.
The size of a property in its internal representation is the length of the name, plus
the size of its value, plus some control data for the property. There is also some
control data for the set of properties after one property is added to the message.
If you exceed this maximum length when using a message property MQI call, the
call fails with reason code MQRC_PROPERTY_NAME_LENGTH_ERR.
Because there is no maximum property name length in JMS, it is possible for a JMS
application to set a valid JMS property name that is not a valid WebSphere MQ
MQ property name when stored in an MQRFH2 structure.
In this case, when parsed, only the first 4095 characters of the property name are
used; the following characters are truncated. This could cause an application using
selectors to fail to match a selection string, or to match a string when not expecting
to, since more than one property might truncate to the same name. When a
property name is truncated, MQ issues an error log message.
All property names must follow the rules defined by the Java Language
Specification for Java Identifiers, with the exception that Unicode character U+002E
(“.”) is permitted as part of the name - but not the start. The rules for Java
Identifiers equate to those contained in the JMS specification for property names.
White space characters and comparison operators are prohibited. Embedded nulls
are allowed in a property name but not recommended. If you use embedded nulls,
this prevents the use of the MQVS_NULL_TERMINATED constant when used
with the MQCHARV structure to specify variable length strings.
Keep property names simple because applications can select messages based on the
property names and the conversion between the character set of the name and of
the selector might cause the selection to fail unexpectedly.
WebSphere MQ property names use character U+002E (“.”) for logical grouping of
properties. This divides up the namespace for properties. The properties with the
following prefixes, in any mixture of lower or upper case are reserved for use by
the product:
v mcd
v jms
v usr
v mq
v sib
v wmq
v Root
v Body
A good way to avoid name clashes is to ensure that all applications prefix their
message properties with their Internet domain name. For example, if you are
developing an application using domain name “ourcompany.com” you could name
all properties with the prefix “com.ourcompany”. This naming convention also
See Property name restrictions for further information about the use of property
names.
Most message descriptor fields can be treated as properties. The property name is
constructed by adding a prefix to the message descriptor field’s name.
Specify <Field> with the same case as for the MQMD structure fields in the C
language declaration. For example, the property name Root.MQMD.AccountingToken
accesses the AccountingToken field of the message descriptor.
The StrucId and Version fields of the message descriptor are not accessible using
the above syntax.
Message descriptor fields are never represented in an MQRFH2 header as for other
properties.
If the message data starts with an MQMDE that is honored by the queue manager,
the MQMDE fields can be accessed using the Root.MQMD.<Field> notation
described above. In this case the MQMDE fields are treated as logically part of the
MQMD from a properties perspective. See the section “MQMDE specified on
MQPUT and MQPUT1 calls” in Overview of MQMDE.
The data type of a property value must be one of the following values:
v MQBOOL
A property can exist but have no defined value; it is a null property. A null
property is different from a byte or character string property (MQBYTE[ ] and
MQCHAR[ ] respectively) that has a defined but empty value, that is, one with a
zero-length value.
Byte string is not a valid property data type in JMS or XMS. You are advised not to
use byte string properties in the <usr> folder.
You can use the correlation identifier in any way that you like. One intended use
of this field is for applications to copy the message identifier of a request message
into the CorrelId field of a reply message. Where possible use the CorrelId in
preference to the MsgId if you want to associate an application-provided identity
with a message. When retrieving a specific message on the distributed platforms,
the queue manager is then optimized for retrieving messages by CorrelId (rather
than by MsgId).
The group identifier is usually generated by the queue manager when the first
message of a group is put onto a queue. The MsgSeqNumber field identifies the
position of the message within the group and the Offset field identifies the
segments within the message.
Where more than one message meets the combined selection criteria, the
MsgDeliverySequence attribute of the queue determines whether messages are
selected in FIFO (first in, first out) or priority order. When messages have equal
priority, they are selected in FIFO order. For more information, see “The order in
which messages are retrieved from a queue” on page 131.
Selectors
A message selector is a variable-length string used by an application to register its
interest in only those messages whose properties satisfy the Structured Query
Language (SQL) query that the selection string represents.
The CCSID associated with the selector string is set via the VSCCSID field of the
MQCHARV structure. The value used must be a CCSID that is supported for
selector strings. The code pages supported are listed within the Code Page
Conversion topic in the WebSphere MQ Application Programming Reference.
The default value for the VSCCSID field is MQCCSI_APPL, which indicates that the
CCSID of the selection string is equal to the queue manager CCSID, or the client
CCSID if connected through a client. The MQCCSI_APPL constant can however be
overridden by an application redefining it before compiling.
If the MQCHARV selector represents a NULL string, no selection takes place for
that message consumer and messages are delivered as if a selector had not been
used.
The maximum length of a selection string is limited only by what can be described
by the MQCHARV field VSLength.
The SelectionString is returned on the output from an MQSUB call using the
MQSO_RESUME subscribe option, if you have provided a buffer and there is a
positive buffer length in VSBufSize. If you do not provide a buffer, only the length
of the selection string is returned in the VSLength field of the MQCHARV. If the
buffer provided is smaller than the space required to return the field, only
VSBufSize bytes are returned in the provided buffer.
An application cannot alter a selection string without first closing either the handle
to the queue (for MQOPEN), or subscription (for MQSUB). A new selection string
can then be specified on a subsequent MQOPEN or MQSUB call.
MQOPEN
Use MQCLOSE to close the opened handle, then specify a new selection
string on a subsequent MQOPEN call.
MQSUB
Use MQCLOSE to close the returned subscription handle (hSub), then
specify a new selection string on a subsequent MQSUB call.
MQOPEN
(APP 1)
ObjectName = "MyDestQ"
hObj MyDestQ
MQSUB
(APP 1)
SelectionString = "Sport = 'Football'"
hObj ResultsTopic
TopicString = "ResultsTopic" MyDestQ
DELIVERED
ResultsTopic
League = 'Premiership'
MyDestQ Sport = 'Football'
Message
NOT DELIVERED
ResultsTopic
League = 'Premiership'
MyDestQ Sport = 'Cricket'
Message
DELIVERED
ResultsTopic
League = 'Div 2'
Sport = 'Football'
MyDestQ
Message
MQGET
(APP 1) hObj
DELIVERED
League = 'Premiership'
Sport = 'Football'
MyDestQ
Message
DELIVERED
Figure 4 on page 34 shows the process of selection using the MQOPEN call.
MQPUT
Application 2
League = 'Div 2'
Sport = 'Football'
SportQ
Message
MQPUT
Application 2
League = 'Premiership'
Sport = 'Football'
SportQ
Message
MQGET
(APP 1) hObj
NOT DELIVERED
DELIVERED
League = 'Premiership'
Sport = 'Football'
SportQ
Message
MQRC_NO_MSG_AVAILABLE
SportQ
The main use for the selector on the MQOPEN call is for the point-to-point case
where an application can elect to receive only those messages on a queue that
match a selector. The example above shows a simple scenario where two messages
are put to a queue opened by MQOPEN but only one is received by the
application getting it, as it is the only one that matches a selector.
Selection behavior:
The fields in an MQMDE structure are considered to be the message properties for
the corresponding message descriptor properties if the MQMD:
v Has format MQFMT_MD_EXTENSION
v Is immediately followed by a valid MQMDE structure
v Is version one or contains the default version two fields only
It is possible for a selection string to resolve to either TRUE or FALSE before any
matching against message properties takes place. This might be the case if, for
instance, the selection string is set to, for example:
"TRUE <>FALSE"
Such early evaluation is guaranteed to take place only when there are no message
property references in the selection string.
For example, a message might still satisfy a selection string like ‘Color IS NULL’,
where ’Color’ does not exist as a message property in the message.
Note that selection can be performed only on the properties associated with a
message, not the message itself.
Each message property has a type associated with it, and when you perform a
selection, you must ensure that the values used in expressions to test message
properties are of the correct type. If a type mismatch occurs, the expression in
question resolves to FALSE.
It is your responsibility to ensure that the selection string and message properties
use compatible types.
The order in which a message selector is evaluated is from left to right within a
precedence level. You can use parentheses to change this order. Predefined selector
literals and operator names are written here in upper case; however, they are not
case-sensitive.
The following message selector selects messages with a message type of car, color
of blue, and weight greater than 2500 lbs:
"JMSType = ’car’ AND color = ’blue’ AND weight > 250"
Familiarize yourself with these rules about how selection strings are interpreted
and character restrictions to avoid potential problems when using selectors.
This process provides a new programming style that can simplify the design and
implementation of new applications, especially those that process multiple input
queues or subscriptions.
MQCONN
MQCB(hObj1, func1)
MQCB(hObj2, func1)
Func1(...)
MQCTL(CONSUME_START)
Process message
Pause, perform non MQ
function. or use a
different hConn.
MQPUT1(md.ReplyQ, ...)
MQCTL(CONSUME_STOP)
return
MQDISC
The difference from the asynchronous case is that control doesn’t return to the
issuer of MQCTL until all of the consumers have deactivated themselves; that is
one consumer has issued an MQCTL STOP request or the queue manager quiesces.
Func1(...)
MQCB(hObj1, func1)
MQDISC return
Figure 6. Single Threaded Message Driven application consuming from two queues
Message groups
Segmentation is not supported on WebSphere MQ for z/OS.
Messages can occur within groups. This allows ordering of messages (see “Logical
and physical ordering” on page 131), and, except on WebSphere MQ for z/OS,
segmentation of large messages (see “Message segmentation” on page 144) within
the same group.
Note: The term message is used here to denote one item on a queue, such
as would be returned by a single MQGET that does not specify
MQGMO_COMPLETE_MSG.
Figure 7 shows a group of logical messages:
Group
Group
For a description of logical and physical messages, see “Logical and physical
ordering” on page 131. For further information about segmenting messages, see
“Message segmentation” on page 144.
Message persistence
Persistent messages are written to logs and queue data files.
When you create a message, if you initialize the message descriptor (MQMD)
using the defaults, the persistence for the message is taken from the
DefPersistence attribute of the queue specified in the MQOPEN command.
Alternatively, you can set the persistence of the message using the Persistence
field of the MQMD structure to define the message as persistent or nonpersistent.
The performance of your application is affected when you use persistent messages;
the extent of the effect depends on the performance characteristics of the machine’s
I/O subsystem and how you use the syncpoint options on each platform:
v A persistent message, outside the current unit of work, is written to disk on
every put and get operation. See “Committing and backing out units of work”
on page 183.
v In WebSphere MQ on UNIX systems, WebSphere MQ for z/OS, and WebSphere
MQ for Windows, a persistent message within the current unit of work is logged
only when the unit of work is committed (and the unit of work could contain
many queue operations).
Nonpersistent messages can be used for fast messaging. See the WebSphere MQ
Application Programming Reference and WebSphere MQ Intercommunications for further
information about fast messages.
You can:
v Attempt to put the message on the queue again.
v Request that the message is returned to the sender.
v Put the message on the dead-letter queue.
An application can detect messages that are caught up in such a loop by testing
the BackoutCount field of MQMD. The application can either correct the situation,
or issue a warning to an operator.
In WebSphere MQ for z/OS, to ensure that the backout count for private queues
survives restarts of the queue manager, set the HardenGetBackout attribute to
MQQA_BACKOUT_HARDENED; otherwise, if the queue manager has to restart, it
For more information on committing and backing out messages, see “Committing
and backing out units of work” on page 183.
Using the MQMD structure, specify the name of the queue to which you want
reply and report messages sent, in the ReplyToQ field. Specify the name of the
queue manager that owns the reply-to queue in the ReplyToQMgr field.
If you leave the ReplyToQMgr field blank, the queue manager sets the contents of
the following fields in the message descriptor on the queue:
ReplyToQ
If ReplyToQ is a local definition of a remote queue, the ReplyToQ field is set
to the name of the remote queue; otherwise this field is not changed.
ReplyToQMgr
If ReplyToQ is a local definition of a remote queue, the ReplyToQMgr field is
set to the name of the queue manager that owns the remote queue;
otherwise the ReplyToQMgr field is set to the name of the queue manager to
which your application is connected.
Note: You can request that a queue manager makes more than one attempt to
deliver a message, and you can request that the message is discarded if it fails. If
the message, after failing to be delivered, is not to be discarded, the remote queue
manager puts the message on its dead-letter (undelivered message) queue (see
“Using the dead-letter (undelivered message) queue” on page 66).
Message context
Message context information allows the application that retrieves the message to
find out about the originator of the message.
All context information is stored in the context fields of the message descriptor.
The type of information falls into identity, origin, and user context information.
Identity context
Identity context information identifies the user of the application that first put the
message on a queue:
v The queue manager fills the UserIdentifier field with a name that identifies the
user; the way that the queue manager can do this depends on the environment
in which the application is running.
v The queue manager fills the AccountingToken field with a token or number that
it determined from the application that put the message.
v Applications can use the ApplIdentityData field for any extra information that
they want to include about the user (for example, an encrypted password).
For information on how the queue manager fills the UserIdentifier and
AccountingToken fields, see the descriptions of these fields in the WebSphere MQ
Application Programming Reference.
Applications that pass messages from one queue manager to another should also
pass on the identity context information so that other applications know the
identity of the originator of the message.
Origin context
Origin context information describes the application that put the message on the
queue on which the message is currently stored. The message descriptor contains
the following fields for origin context information:
PutApplType The type of application that put the message (for example, a CICS
transaction).
PutApplName The name of the application that put the message (for example, the
name of a job or transaction).
PutDate The date on which the message was put on the queue.
PutTime The time at which the message was put on the queue.
ApplOriginData Any extra information that an application wants to include about
the origin of the message. For example, it could be set by suitably
authorized applications to indicate whether the identity data is
trusted.
An application with enough authority can provide its own context. This allows
accounting information to be preserved when a single user has a different user ID
on each of the systems that process a message that they have originated.
User context
User context allows an application to pass properties around a queue manager
network without direct support of message handles on all the intermediate
applications.
You can include any message property in the user context, by setting the Context
field of the message property descriptor (MQPD) when you make the MQSETMP
call.
WebSphere MQ objects
The WebSphere MQ objects are:
v Queue managers
v Queue-sharing groups (WebSphere MQ for z/OS only), although these are not
strictly objects.
v Queues
v Administrative topic objects
v Namelists
v Process definitions
v Authentication information objects
v Channels
v Storage classes (WebSphere MQ for z/OS only)
v Listeners
v Services (not WebSphere MQ for z/OS)
Queue managers define the properties (known as attributes) of these objects. The
values of these attributes affect the way in which WebSphere MQ processes these
objects. From your applications, you use the Message Queue Interface (MQI) to
control these objects. Objects are identified by an object descriptor (MQOD) when
addressed from a program.
When you use WebSphere MQ commands to define, alter, or delete objects, for
example, the queue manager checks that you have the required level of authority
to perform these operations. Similarly, when an application uses the MQOPEN call
to open an object, the queue manager checks that the application has the required
level of authority before it allows access to that object. The checks are made on the
name of the object being opened.
Queue managers
A queue manager supplies an application with WebSphere MQ services.
A program must have a connection to a queue manager before it can use the
services of that queue manager. A program can make this connection explicitly
(using the MQCONN or MQCONNX call), or the connection might be made
implicitly (this depends on the platform and the environment in which the
program is running).
Queues belong to queue managers, but programs can send messages to queues
that belong to any queue manager.
For a full description of all the attributes, see the WebSphere MQ Application
Programming Reference.
Queue-sharing groups
Supported only on WebSphere MQ for z/OS.
Queue-sharing groups are not strictly objects, but are mentioned here for
convenience.
Queue managers that can access the same set of shared queues form a group called
a queue-sharing group (QSG), and they communicate with each other by means of a
coupling facility (CF) that stores the shared queues. A shared queue is a type of local
queue whose messages can be accessed by one or more queue managers that are in
a queue-sharing group. (This is not the same as a queue being shared by more than
one application, using the same queue manager.) See the WebSphere MQ for z/OS
Concepts and Planning Guide for a full discussion of shared queues and
queue-sharing groups.
Queues
A WebSphere MQ queue is a named object on which applications can put messages,
and from which applications can get messages.
Before a message can be put on a queue, the queue must have already been
created. A queue is owned by a queue manager, and that queue manager can own
many queues. However, each queue must have a name that is unique within that
queue manager.
Before using a queue, you must open the queue, specifying what you want to do
with it. For example, you can open a queue for:
v Browsing messages only (not retrieving them)
v Retrieving messages (and either sharing the access with other programs, or with
exclusive access)
v Putting messages on the queue
v Inquiring about the attributes of the queue
v Setting the attributes of the queue
For a complete list of the options that you can specify when you open a queue, see
the description of the MQOPEN call in the WebSphere MQ Application Programming
Reference.
Types of queue
The types of queue that WebSphere MQ supports for applications to use are:
Local and remote queues
A queue is known to a program as local if it is owned by the queue
manager to which the program is connected; the queue is known as remote
if it is owned by a different queue manager. The important difference
between these two types of queue is that you can get messages only from
local queues. (You can put messages on both types of queue.)
The queue definition object, created when you define a local queue, holds
the definition information of the queue as well as the physical messages
put on the queue. The queue definition object, created when you define a
remote queue, only holds the information necessary for the local queue
manager to locate the queue to which you want your message to go. This
object is known as the local definition of a remote queue. All the attributes of
the remote queue are held by the queue manager that owns it, because it is
a local queue to that queue manager.
Shared queues
Shared queues are available only on WebSphere MQ for z/OS.
A shared queue is a type of local queue whose messages can be accessed by
one or more queue managers that are in a queue-sharing group. (This is
not the same as a queue being shared by more than one application, using
the same queue manager.) Shared queues are held by a coupling facility
(CF), and are accessible by any queue manager in the queue-sharing group.
Each shared queue in a queue-sharing group must have a name that is
unique within that group. See the WebSphere MQ for z/OS Concepts and
Planning Guide for a full discussion of shared queues and queue-sharing
groups.
Alias queues
To your program, an alias queue appears to be a queue, but it is really a
WebSphere MQ object that you can use to access another queue or a topic.
This means that more than one program can work with the same queue,
accessing it using different names. For more information about topic
aliases, see WebSphere MQ Publish/Subscribe User’s Guide.
Each queue manager can have some local queues that it uses for special purposes:
Transmission queues
A transmission queue is a local queue that holds messages destined for a
remote queue. The messages are forwarded to their destination queue by
WebSphere MQ when a communication program and link are available.
Initiation queues
An initiation queue is a local queue on which the queue manager puts a
message to start an application when certain conditions (such as more than
10 messages arriving, for example) are met on a local queue.
Dead-letter (undelivered message) queue
The dead-letter queue is a local queue on which the queue manager and
applications put messages they cannot deliver. You need to process any
messages that arrive on this queue.
System command queue
The system command queue is a queue to which suitably authorized
applications can send WebSphere MQ commands.
System default queues
When you create a queue (other than a dynamic queue), WebSphere MQ
uses the queue definitions stored in the system default queues.
Channel queues
Channel queues are used for distributed queue management.
Event queues
Event queues hold event messages. These messages are reported by the
queue manager or a channel.
These special queues are described in greater detail in the following sections.
You can find the values of all the attributes using the MQINQ call.
The attributes that are common to more than one type of queue are:
QName Name of the queue
QType Type of the queue
QDesc Text description of the queue
InhibitGet
Whether or not programs are allowed to get messages from the queue
(although you can never get messages from remote queues)
InhibitPut
Whether or not programs are allowed to put messages on the queue
DefPriority
Default priority for messages put on the queue
DefPersistence
Default persistence for messages put on the queue
Scope (not supported on z/OS)
Controls whether an entry for this queue also exists in a name service
Remote queues
To a program, a queue is remote if it is owned by a different queue manager to the
one to which the program is connected.
Where a communication link has been established, a program can send a message
to a remote queue. A program can never get a message from a remote queue.
When opening a remote queue, to identify the queue you must specify either:
v The name of the local definition that defines the remote queue.
To create a local definition of a remote queue use the DEFINE QREMOTE
command; on WebSphere MQ for i5/OS, use the CRTMQMQ command.
From the viewpoint of an application, this is the same as opening a local queue.
An application does not need to know if a queue is local or remote.
v The name of the remote queue manager and the name of the queue as it is
known to that remote queue manager.
Local definitions of remote queues have three attributes in addition to the common
attributes described in “Attributes of queues.” These are RemoteQName (the name
If you use the MQINQ call against the local definition of a remote queue, the
queue manager returns the attributes of the local definition only, that is the remote
queue name, the remote queue manager name, and the transmission queue name,
not the attributes of the matching local queue in the remote system.
Alias queues
An alias queue is a WebSphere MQ object that you can use to access another queue
or a topic.
The queue resulting from the resolution of an alias name (known as the base
queue) can be a local queue, the local definition of a remote queue, or a shared
queue (a type of local queue only available on WebSphere MQ for z/OS). It can
also be either a predefined queue or a dynamic queue, as supported by the
platform.
An alias name can also resolve to a topic. If an application currently puts messages
onto a queue, it can be made to publish to a topic by making the queue name an
alias for the topic. No change to the application code is necessary. For more
information about topic aliases, see WebSphere MQ Publish/Subscribe User’s Guide.
Alternatively, authorization can be set to inhibit put operations for the alias name,
but allow them for the base queue.
In some applications, the use of alias queues means that system administrators can
easily change the definition of an alias queue object without having to get the
application changed.
WebSphere MQ makes authorization checks against the alias name when programs
try to use that name. It does not check that the program is authorized to access the
name to which the alias resolves. A program can therefore be authorized to access
an alias queue name, but not the resolved queue name.
The InhibitGet and InhibitPut attributes (see “Attributes of queues” on page 53)
of alias queues belong to the alias name. For example, if the alias-queue name
The DefPriority and DefPersistence attributes also belong to the alias name. So,
for example, you can assign different default priorities to different aliases of the
same base queue. Also, you can change these priorities without having to change
the applications that use the aliases.
Model queues
A model queue is a template of a queue definition that you use when creating a
dynamic queue.
You specify the name of a model queue in the object descriptor (MQOD) of your
MQOPEN call. Using the attributes of the model queue, the queue manager
dynamically creates a local queue for you.
You can specify a name (in full) for the dynamic queue, or the stem of a name (for
example, ABC) and let the queue manager add a unique part to this, or you can let
the queue manager assign a complete unique name for you. If the queue manager
assigns the name, it puts it in the MQOD structure.
You cannot issue an MQPUT1 call directly to a model queue , but you can issue an
MQPUT1 to the dynamic queue that has been created by opening a model queue.
The attributes of a model queue are a subset of those of a local queue. For a fuller
description, see the WebSphere MQ Application Programming Reference.
Dynamic queues
When an application program issues an MQOPEN call to open a model queue, the
queue manager dynamically creates an instance of a local queue with the same
attributes as the model queue.
Depending on the value of the DefinitionType field of the model queue, the queue
manager creates either a temporary or permanent dynamic queue (See “Creating
dynamic queues” on page 107).
The server can then place the reply message on the reply-to queue. Finally, the
client could process the reply, and close the reply-to queue with the delete option.
Transmission queues
When an application sends a message to a remote queue, the local queue manager
stores the message in a special local queue, called a transmission queue.
A message channel agent (channel program), or intra-group queuing agent when using
intra-group queuing on WebSphere MQ for z/OS, is associated with the
transmission queue and the remote queue manager, and this delivers the message.
When the message has been delivered, it is deleted from the transmission queue.
The message might have to pass through many queue managers (or nodes) on its
journey to its final destination. There must be a transmission queue defined at each
queue manager along the route, each holding messages waiting to be transmitted
to the next node. (A shared transmission queue is used when using intra-group
queuing on WebSphere MQ for z/OS.) There can be several transmission queues
defined at a particular queue manager. A given transmission queue holds messages
whose next destination is the same queue manager, although the messages might
have different eventual destinations. There might also be several transmission
queues for the same remote queue manager, with each one being used for a
different type of service, for example.
Initiation queues
An initiation queue is a local queue on which the queue manager puts a trigger
message when a trigger event occurs on an application queue.
A trigger event is an event (for example, more than 10 messages arriving) that an
application designer intends the queue manager to use as a cue, or trigger, to start
a program to process the queue. For more information on how triggering works,
see “Starting WebSphere MQ applications using triggers” on page 195.
When the queue manager puts a message on the dead-letter queue, it adds a
header to the message. This includes such information as the intended destination
Applications can also use the queue for messages that they cannot deliver. For
more information, see “Using the dead-letter (undelivered message) queue” on
page 66.
Topics inherit their attributes from the first parent administrative node found in
their topic tree. If there are no administrative topic nodes in a particular topic tree,
then all topics will inherit their attributes from the base topic object,
SYSTEM.BASE.TOPIC.
You can create an administrative topic object at any node in a topic tree by
specifying that node’s topic string in the TOPICSTR attribute of the administrative
topic object. You can also define other attributes for the administrative topic node.
For more information about these attributes, see the WebSphere MQ Script (MQSC)
Command Reference, or the WebSphere MQ Programmable Command Formats and
Administration Interface. Each administrative topic object will, by default, inherit its
attributes from its closest parent administrative topic node.
Administrative topic objects can also be used to hide the full topic tree from
application developers. If an administrative topic object named FOOTBALL.US is
created for the topic /Sport/American Football, an application can publish or
subscribe to the object name FOOTBALL.US instead of the string /Sport/American
Football with the same result.
Namelists
A namelist is a WebSphere MQ object that contains a list of cluster names, queue
names or authentication information object names. In a cluster, it can be used to
identify a list of clusters for which the queue manager holds the repositories.
You can define and modify namelists only using the operations and control panels
of WebSphere MQ for z/OS or MQSC commands.
Programs can use the MQI to find out which queues are included in these
namelists. The organization of the namelists is the responsibility of the application
designer and system administrator.
Process definitions
To allow an application to be started without the need for operator intervention
(described in “Starting WebSphere MQ applications using triggers” on page 195),
the attributes of the application must be known to the queue manager. These
attributes are defined in a process definition object.
The ProcessName attribute is fixed when the object is created; you can change the
others using the WebSphere MQ commands or the WebSphere MQ for z/OS
operations and control panels. You can inquire about the values of all the attributes
using the MQINQ call.
For a full description of the attributes of process definitions, see the WebSphere MQ
Application Programming Reference.
For a full description of the attributes of authentication information objects, see the
WebSphere MQ Application Programming Reference. For more information about SSL,
see WebSphere MQ Security.
Channels
A channel is a communication link used by distributed queue managers.
You need to consider these when designing your application, but programs are
unaware of WebSphere MQ channel objects. For more information, see WebSphere
MQ Intercommunications and WebSphere MQ Clients.
Storage classes
Supported only on WebSphere MQ for z/OS.
A storage class maps one or more queues to a page set. This means that messages
for that queue are stored (subject to buffering) on that page set.
For further information about storage classes, see the WebSphere MQ for z/OS
Concepts and Planning Guide.
Listeners
Listeners are processes that accept network requests from other queue managers, or
client applications, and start associated channels.
Listener processes can be started using the runmqlsr control command. Listeners
are available on all platforms.
Listener objects are WebSphere MQ objects that allow you to manage the starting
and stopping of listener processes from within the scope of a queue manager.
Listener objects are not supported on WebSphere MQ for z/OS. By defining
attributes of a listener object you do the following:
v Configure the listener process.
v Specify whether the listener process automatically starts and stops when the
queue manager starts and stops.
Services
Service objects are a way of defining programs to be executed when a queue
manager starts or stops.
The character set to use for naming all WebSphere MQ objects is as follows:
v Uppercase A–Z
v Lowercase a–z (but there are restrictions on the use of lowercase letters for z/OS
console support)
On systems using EBCDIC Katakana you cannot use lowercase characters.
v Numerics 0–9
v Period (.)
v Forward slash (/)
v Underscore (_)
v Percent sign (%)
Note:
1. Leading or embedded blanks are not allowed.
2. Avoid using names with leading or trailing underscores, because they cannot
be handled by the WebSphere MQ for z/OS operations and control panels.
3. Any name that is less than the full field length can be padded to the right with
blanks. All short names that are returned by the queue manager are always
padded to the right with blanks.
4. Any structure to the names (for example, the use of the period or underscore)
is not significant to the queue manager.
5. On i5/OS systems, within CL, lowercase a-z, forward slash (/), and percent (%)
are special characters. If you use any of these characters in a name, enclose the
name in quotation marks. Lowercase a-z characters are changed to uppercase if
the name is not enclosed in quotation marks.
6. On Windows systems, the first character of a queue manager name cannot be a
forward slash (/).
Queue names
The name of a queue has two parts:
v The name of a queue manager
v The local name of the queue as it is known to that queue manager
To refer to a remote queue, a program must include the name of the queue
manager in the full queue name, or there must be a local definition of the remote
queue.
When an application uses a queue name, that name can be either the name of a
local queue (or an alias to one) or the name of a local definition of a remote queue,
but the application does not need to know which, unless it needs to get a message
from the queue (when the queue must be local). When the application opens the
queue object, the MQOPEN call performs a name resolution function to determine
on which queue to perform subsequent operations. The significance of this is that
the application has no built-in dependency on particular queues being defined at
particular locations in a network of queue managers. Therefore, if a system
administrator relocates queues in the network, and changes their definitions, the
applications that use those queues do not need to be changed.
Channel names
Channels can have names up to 20 characters long.
This chapter gives advice on how to handle both types of error, under these
headings:
v “Locally determined errors” on page 63
If you are using the asynchronous put facility, errors are not reported immediately.
Use the MQSTAT call to retrieve status information about previous asynchronous
put operations.
To show whether or not a call is successful, the queue manager returns a completion
code when the call completes. There are three completion codes, indicating success,
partial completion, and failure of the call. The queue manager also returns a reason
code that indicates the reason for the partial completion or the failure of the call.
The completion and reason codes for each call are listed with the description of
that call in the WebSphere MQ Application Programming Reference. For more detailed
information, including ideas for corrective action, see:
v WebSphere MQ for z/OS Messages and Codes for WebSphere MQ for z/OS
v WebSphere MQ Messages for all other WebSphere MQ platforms
Design your programs to handle all the return codes that can arise from each call.
System interruptions
Your application might be unaware of any interruption if the queue manager to
which it is connected has to recover from a system failure. However, you must
design your application to ensure that your data is not lost if such an interruption
occurs.
The methods that you can use to make sure that your data remains consistent
depends on the platform on which your queue manager is running:
z/OS In the CICS and IMS environments, you can make MQPUT and MQGET
calls within units of work that are managed by CICS or IMS. In the batch
environment, you can make MQPUT and MQGET calls in the same way,
but you must declare syncpoints using:
v The WebSphere MQ for z/OS MQCMIT and MQBACK calls (see
“Committing and backing out units of work” on page 183), or
v The z/OS Transaction Management and Recoverable Resource Manager
Services (RRS) to provide two-phase syncpoint support. RRS allows you
to update both WebSphere MQ and other RRS-enabled product
resources, such as DB2 stored procedure resources, within a single
Use persistent messages for carrying all data that you cannot afford to lose.
Persistent messages are reinstated on queues if the queue manager has to recover
from a failure. With WebSphere MQ on UNIX systems and WebSphere MQ for
Windows, an MQGET or MQPUT call within your application will fail at the point
of filling all the log files, with the message MQRC_RESOURCE_PROBLEM. For
more information on log files on AIX, HP-UX, Linux, Solaris, and Windows
systems, see the WebSphere MQ System Administration Guide; for z/OS see the
WebSphere MQ for z/OS Concepts and Planning Guide.
If the queue manager is forced to stop (that is, stop without quiescing),
applications will receive the MQRC_CONNECTION_BROKEN reason code when
they make MQI calls. At this point, exit the application or, alternatively, on
WebSphere MQ for i5/OS, WebSphere MQ on UNIX systems, and WebSphere MQ
for Windows, issue an MQDISC call.
The queue manager maintains a count (in the BackoutCount field of the message
descriptor) of the number of times that happens. It maintains this count in the
descriptor of each message that is affected. This count can provide valuable
information about the efficiency of an application. Messages whose backout counts
are increasing over time are being repeatedly rejected; design your application so
that it analyzes the reasons for this and handles such messages accordingly.
Also, on WebSphere MQ for z/OS, when you remove messages from a queue
within a unit of work, you can mark one message so that it is not made available
again if the unit of work is backed out by the application. The marked message is
treated as if it has been retrieved under a new unit of work. You mark the message
that is to skip backout using the MQGMO_MARK_SKIP_BACKOUT option (in the
MQGMO structure) when you use the MQGET call. See “Skipping backout” on
page 152 for more information about this technique.
Within your application you can create (MQPUT) report messages as well as select
the option to receive them (in which case they are sent by either another
application or by a queue manager).
However, the Report field must initially be analyzed to determine whether the
application that sent the message is interested in being informed of any problems.
Having determined that a report message is required, you have to decide:
v Whether you want to include the entire original message, just the first 100 bytes
of data, or none of the original message.
v What to do with the original message. You can discard it or let it go to the
dead-letter queue.
v Whether the contents of the MsgId and CorrelId fields are needed as well.
Use the Feedback field to indicate the reason for the report message being
generated. Put your report messages on an application’s reply-to queue. Refer to
the WebSphere MQ Application Programming Reference for further information.
When you send a message to another application, you are not informed of any
problems unless you complete the Report field to indicate the feedback that you
require. The options available to you are in the WebSphere MQ Application
Programming Reference.
The queue manager sets the Feedback field of the report message to indicate the
reason for the error; for example, the target queue does not exist. Your programs
should do the same.
For more information on report messages, see “Report messages” on page 19.
For example, the queue that you are targeting might be full, or might not even
exist. If your message has to be handled by other intermediate queue managers on
the route to the target queue, any of these could find an error.
Each option has its merits, but you might not want to retry putting a message if
the reason that the MQPUT failed was because the destination queue was full. In
this instance, putting it on the dead-letter queue allows you to deliver it to the
correct destination queue later on.
If the MsgRetryExitId field is blank, the values in the attributes MsgRetryCount and
MsgRetryInterval are used.
If the MsgRetryExitId field is not blank, the exit program of this name runs. For
more information on using your own exit programs, see WebSphere MQ
Intercommunications.
When the queue manager puts a message on this queue, it adds a header to the
message, the format of which is described by the dead-letter header (MQDLH)
structure, in the WebSphere MQ Application Programming Reference. This header
includes the name of the target queue and the reason that the message was put on
the dead-letter queue. It must be removed and the problem must be resolved
before the message is put on the intended queue. Also, the queue manager changes
the Format field of the message descriptor (MQMD) to indicate that the message
contains an MQDLH structure.
MQDLH structure
You are recommended to add an MQDLH structure to all messages that you put
on the dead-letter queue; however, if you intend to use the dead-letter handler
provided by certain WebSphere MQ products, you must add an MQDLH structure
to your messages.
The addition of the header to a message might make the message too long for the
dead-letter queue, so always make sure that your messages are shorter than the
maximum size allowed for the dead-letter queue, by at least the value of the
MQ_MSG_HEADER_LENGTH constant. The maximum size of messages allowed
on a queue is determined by the value of the MaxMsgLength attribute of the queue.
For the dead-letter queue, make sure that this attribute is set to the maximum
allowed by the queue manager. If your application cannot deliver a message, and
the message is too long to be put on the dead-letter queue, follow the advice given
in the description of the MQDLH structure.
Ensure that the dead-letter queue is monitored, and that any messages arriving on
it get processed. The dead-letter queue handler runs as a batch utility and can be
used to perform various actions on selected messages on the dead-letter queue. For
further details, see WebSphere MQ System Administration Guide for WebSphere MQ
for AIX, HP-UX, Linux, Solaris, and Windows systems; for WebSphere MQ for
z/OS see WebSphere MQ for z/OS System Administration Guide; for i5/OS see
WebSphere MQ for i5/OS System Administration Guide.
If data conversion is necessary, the queue manager converts the header information
when you use the MQGMO_CONVERT option on the MQGET call. If the process
putting the message is an MCA, the header is followed by all the text of the
original message.
Messages put on the dead-letter queue might be truncated if they are too long for
this queue. A possible indication of this situation is the messages on the dead-letter
queue being the same length as the value of the MaxMsgLength attribute of the
queue.
There are two ways to deal with the messages that you have recovered from the
dead-letter queue:
1. If the message is for a local queue:
v Carry out any code translations required to extract the application data
v Carry out code conversions on that data if this is a local function
v Put the resulting message on the local queue with all the detail of the
message descriptor restored
2. If the message is for a remote queue, put the message on the queue.
The remaining chapters in this part of the book describe how to use these features.
Detailed descriptions of the calls, structures, data types, return codes, and
constants are given in the WebSphere MQ Application Programming Reference.
Calls
The calls in the MQI can be grouped as follows:
MQCONN, MQCONNX, and MQDISC
Use these calls to connect a program to (with or without options), and
disconnect a program from, a queue manager. If you write CICS programs
for z/OS, you do not need to use these calls. However, you are
recommended to use them if you want to port your application to other
platforms.
MQOPEN and MQCLOSE
Use these calls to open and close an object, such as a queue.
MQPUT and MQPUT1
Use these calls to put a message on a queue.
MQGET
Use this call to browse messages on a queue, or to remove messages from
a queue.
MQSUB, MQSUBRQ
Use these calls to register a subscription to a topic, and to request
publications matching the subscription.
MQINQ
Use this call to inquire about the attributes of an object.
MQSET
Use this call to set some of the attributes of a queue. You cannot set the
attributes of other types of object.
MQBEGIN, MQCMIT, and MQBACK
Use these calls when WebSphere MQ is the coordinator of a unit of work.
MQBEGIN starts the unit of work. MQCMIT and MQBACK end the unit
of work, either committing or rolling back the updates made during the
unit of work. i5/OS commitment controller is used to coordinate global
units of work on i5/OS. Native start commitment control, commit, and
rollback commands are used.
MQCRTMH, MQBUFMH, MQMHBUF, MQDLTMH
Use these calls to create a message handle, to convert a message handle to
a buffer or a buffer to a message handle, and to delete a message handle.
MQSETMP, MQINQMP, MQDLTMP
Use these calls to set a message property on a message handle, inquire on
a message property, and delete a property from a message handle.
MQCB, MQCB_FUNCTION, MQCTL
Use these calls to register and control a callback function.
The MQI calls are described fully in the WebSphere MQ Application Programming
Reference
Syncpoint calls
Syncpoint calls are available as follows:
Use these calls in z/OS batch programs to tell the queue manager that all the
MQGET and MQPUT operations since the last syncpoint are to be made
permanent (committed) or are to be backed out. To commit and back out changes
in other environments:
CICS Use commands such as EXEC CICS SYNCPOINT and EXEC CICS
SYNCPOINT ROLLBACK.
IMS Use the IMS syncpoint facilities, such as the GU (get unique) to the IOPCB,
CHKP (checkpoint), and ROLB (rollback) calls.
RRS Use MQCMIT and MQBACK or SRRCMIT and SRRBACK as appropriate.
(See “Transaction management and recoverable resource manager services”
on page 187.)
Note: SRRCMIT and SRRBACK are native RRS commands, they are not
MQI calls.
For backward compatibility, the CSQBCMT and CSQBBAK calls are available as
synonyms for MQCMIT and MQBACK. These are described in the WebSphere MQ
Application Programming Reference.
i5/OS calls:
WebSphere MQ for i5/OS provides the MQCMIT and MQBACK commands. You
can also use the i5/OS COMMIT and ROLLBACK commands, or any other
commands or calls that initiate the i5/OS commitment control facilities (for
example, EXEC CICS SYNCPOINT).
Use syncpoint calls in programs to tell the queue manager that all the MQGET and
MQPUT operations since the last syncpoint are to be made permanent (committed)
or are to be backed out. To commit and back out changes in the CICS environment,
use commands such as EXEC CICS SYNCPOINT and EXEC CICS SYNCPOINT
ROLLBACK.
See the WebSphere MQ Application Programming Reference for the syntax used with
the MQXCNVC call, and “Writing data-conversion exits” on page 163 for guidance
on writing and invoking data conversion exits.
Structures
Structures, used with the MQI calls listed in “Calls” on page 70, are supplied in
data definition files for each of the supported programming languages. WebSphere
MQ for z/OS and WebSphere MQ for i5/OS supply files that contain constants for
you to use when filling in some of the fields of these structures. For more
information on these, see “WebSphere MQ data definitions.”
These data types are described fully in the WebSphere MQ Application Programming
Reference.
WebSphere MQ for i5/OS supplies data definitions in the form of COBOL copy
files, RPG copy files, C language include files, and C++ language include files.
For more information about how to use stub programs and library files when you
build an executable application, see Chapter 3, “Building a WebSphere MQ
application,” on page 339. For information about linking to C++ library files, see
WebSphere MQ Using C++.
The stub program provides the first stage of the processing of your calls into
requests that WebSphere MQ for z/OS can process.
Note: If you use the CSQBRSTB stub program, link-edit with ATRSCSS from
SYS1.CSSLIB. (SYS1.CSSLIB is also known as the Callable Services Library). For more
information about RRS see “Transaction management and recoverable resource
manager services” on page 187.
Alternatively, you can dynamically call the stub from within your program. This
technique is described in “Dynamically calling the WebSphere MQ stub” on page
377.
In IMS, you might also need to use a special language interface module that is
supplied by WebSphere MQ.
In WebSphere MQ for i5/OS, link your program to the MQI library files supplied
for the environment in which you are running your application, in addition to
those provided by the operating system.
In a threaded application:
On WebSphere MQ for Windows, you must link your program to the MQI library
files supplied for the environment in which you are running your application, in
addition to those provided by the operating system:
On WebSphere MQ for AIX, you must link your program to the MQI library files
supplied for the environment in which you are running your application, in
addition to those provided by the operating system.
In a non-threaded application:
In a threaded application:
PA-RISC platform:
In a non-threaded application:
In a threaded application:
In a non-threaded application:
In a threaded application:
On WebSphere MQ for Linux, you must link your program to the MQI library files
supplied for the environment in which you are running your application, in
addition to those provided by the operating system.
In a non-threaded application:
In a threaded application:
On WebSphere MQ for Solaris, you must link your program to the MQI library
files supplied for the environment in which you are running your application in
addition to those provided by the operating system.
For a program to communicate with a queue manager, the program must have a
unique identifier by which it knows that queue manager. This identifier is called a
connection handle, sometimes referred to as an Hconn. For CICS programs, the
connection handle is always zero. For all other platforms or styles of programs, the
connection handle is returned by the MQCONN or MQCONNX call when the
program connects to the queue manager. Programs pass the connection handle as
an input parameter when they use the other calls.
For a program to work with a WebSphere MQ object, the program must have a
unique identifier by which it knows that object. This identifier is called an object
handle, sometimes referred to as an Hobj. The handle is returned by the MQOPEN
call when the program opens the object to work with it. Programs pass the object
handle as an input parameter when they use subsequent MQPUT, MQGET,
MQINQ, MQSET, or MQCLOSE calls.
Similarly, the MQSUB call returns a subscription handle or Hsub, which is used to
identify the subscription in subsequent MQGET, MQCB or MQSUBRQ calls, and
certain calls processing message properties use a message handle or Hmsg.
To show whether or not a call is successful, each call returns a completion code
when the call is complete. The completion code is usually either MQCC_OK or
MQCC_FAILED, showing success and failure, respectively. Some calls can return
an intermediate state, MQCC_WARNING, indicating partial success.
Each call also returns a reason code that shows the reason for the failure, or partial
success, of the call. There are many reason codes, covering such circumstances as a
queue being full, get operations not being allowed for a queue, and a particular
queue not being defined for the queue manager. Programs can use the reason code
to decide how to proceed. For example, they can prompt users to change their
input data, then make the call again, or they can return an error message to the
user.
The completion and reason codes for each call are listed with the description of
that call in WebSphere MQ Application Programming Reference. For more detailed
information, including ideas for corrective action, see:
v WebSphere MQ for z/OS Messages and Codes for WebSphere MQ for z/OS
v WebSphere MQ Messages for all other WebSphere MQ platforms
Specifying buffers
The queue manager refers to buffers only if they are required. If you do not
require a buffer on a call or the buffer is zero in length, you can use a null pointer
to a buffer.
Always use datalength when specifying the size of the buffer that you require.
78 WebSphere MQ: Application Programming Guide
When you use a buffer to hold the output from a call (for example, to hold the
message data for an MQGET call, or the values of attributes queried by the
MQINQ call), the queue manager attempts to return a reason code if the buffer
you specify is not valid or is in read-only storage. However, it might not always be
able to return a reason code.
The call interface, and how you can code the calls in each of these languages, is
described in the WebSphere MQ Application Programming Reference.
If you can choose which language to code your programs in, consider the
maximum length of the messages that your programs will process. If your
programs will process only messages of a known maximum length, you can code
them in any of the supported programming languages. But if you do not know the
maximum length of the messages that the programs will have to process, the
language you choose will depend on whether you are writing a CICS, IMS, or
batch application:
IMS and batch
Code the programs in C, PL/I, or assembler language to use the facilities
these languages offer for obtaining and releasing arbitrary amounts of
memory. Alternatively, you could code your programs in COBOL, but use
assembler language, PL/I, or C subroutines to get and release storage.
CICS Code the programs in any language supported by CICS. The EXEC CICS
interface provides the calls for managing memory, if necessary.
Coding in C
Note the information in the following sections when coding WebSphere MQ
programs in C.
Not all parameters that are passed by address need to be specified every time a
function is invoked. Where a particular parameter is not required, a null pointer
The attributes of the function are defined by the MQENTRY macro variable; the
value of this macro variable depends on the environment.
The MQGET, MQPUT, and MQPUT1 functions each have a Buffer parameter that
has an undefined data type. This parameter is used to send and receive the
application’s message data.
Parameters of this sort are shown in the C examples as arrays of MQBYTE. You
can declare the parameters in this way, but it is usually more convenient to declare
them as the structure that describes the layout of the data in the message. The
function parameter is declared as a pointer-to-void, and so the address of any sort
of data can be specified as the parameter on the function invocation.
Data types:
For each data type, the corresponding pointer data type is also defined. The name
of the pointer data type is the name of the elementary or structure data type
prefixed with the letter P to denote a pointer. The attributes of the pointer are
defined by the MQPOINTER macro variable; the value of this macro variable
depends on the environment. The following illustrates how to declare pointer data
types:
#define MQPOINTER /* depends on environment */
...
typedef MQLONG MQPOINTER PMQLONG; /* pointer to MQLONG */
typedef MQMD MQPOINTER PMQMD; /* pointer to MQMD */
Strings of binary data are declared as one of the MQBYTEn data types.
Whenever you copy, compare, or set fields of this type, use the C functions memcpy,
memcmp, or memset:
#include <string.h>
#include "cmqc.h"
MQMD MyMsgDesc;
Do not use the string functions strcpy, strcmp, strncpy, or strncmp because these
do not work correctly with data declared as MQBYTE24.
When the queue manager returns character data to the application, the queue
manager always pads the character data with blanks to the defined length of the
field. The queue manager does not return null-terminated strings, but you can use
them in your input. Therefore, when copying, comparing, or concatenating such
strings, use the string functions strncpy, strncmp, or strncat.
Do not use the string functions that require the string to be terminated by a null
(strcpy, strcmp, and strcat). Also, do not use the function strlen to determine the
length of the string; use instead the sizeof function to determine the length of the
field.
The include file <cmqc.h> defines various macro variables that you can use to
provide initial values for the structures when declaring instances of those
structures. These macro variables have names of the form MQxxx_DEFAULT,
where MQxxx represents the name of the structure. Use them like this:
MQMD MyMsgDesc = {MQMD_DEFAULT};
MQPMO MyPutOpts = {MQPMO_DEFAULT};
For some character fields, the MQI defines particular values that are valid (for
example, for the StrucId fields or for the Format field in MQMD). For each of the
valid values, two macro variables are provided:
v One macro variable defines the value as a string whose length, excluding the
implied null, matches exactly the defined length of the field. For example, (the
symbol represents a blank character):
#define MQMD_STRUC_ID "MD"
#define MQFMT_STRING "MQSTR"
Use this form to initialize the field when an instance of the structure is declared
with values different from those provided by the MQMD_DEFAULT macro
variable.
When a variable number of instances of a structure are required, the instances are
usually created in main storage obtained dynamically using the calloc or malloc
functions.
For the C++ programming language, the header files contain the following
additional statements that are included only when a C++ compiler is used:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
Coding in COBOL
Note the information in the following sections when coding WebSphere MQ
programs in COBOL.
Named constants:
In this book, the names of constants are shown containing the underscore character
(_) as part of the name. In COBOL, you must use the hyphen character (-) in place
of the underscore.
Constants that have character-string values use the single quotation mark character
(’) as the string delimiter. To make the compiler accept this character, use the
compiler option APOST.
The copy file CMQV contains declarations of the named constants as level-10
items. To use the constants, declare the level-01 item explicitly, then use the COPY
statement to copy in the declarations of the constants:
WORKING-STORAGE SECTION.
01 MQM-CONSTANTS.
COPY CMQV.
However, this method causes the constants to occupy storage in the program even
if they are not referred to. If the constants are included in many separate programs
within the same run unit, multiple copies of the constants will exist; this might
result in a significant amount of main storage being used. You can avoid this by
adding the GLOBAL clause to the level-01 declaration:
* Declare a global structure to hold the constants
01 MQM-CONSTANTS GLOBAL.
COPY CMQV.
Names:
In this book, the names of parameters in the descriptions of calls, and the names of
fields in the descriptions of structures are shown in mixed case. In the
assembler-language macros supplied with WebSphere MQ, all names are in
uppercase.
Note: This is important for CICS assembler-language programs that use the
DFHEIENT macro to set up their dynamic storage, but that choose to override the
default DATAREG from R13 to other registers. When the CICS Resource Manager
Interface receives control from the stub, it saves the current contents of the
registers at the address to which R13 is pointing. Failing to reserve a proper save
area for this purpose gives unpredictable results, and will probably cause an abend
in CICS.
Declaring constants:
However, the following constants cannot be defined as equates, and these are not
included when you call the macro using default options:
v MQACT_NONE
v MQCI_NONE
v MQFMT_NONE
v MQFMT_ADMIN
v MQFMT_COMMAND_1
v MQFMT_COMMAND_2
v MQFMT_DEAD_LETTER_HEADER
v MQFMT_EVENT
v MQFMT_IMS
v MQFMT_IMS_VAR_STRING
v MQFMT_PCF
v MQFMT_STRING
v MQFMT_TRIGGER
v MQFMT_XMIT_Q_HEADER
CMQA is protected against multiple declaration, so you can include it many times.
However, the keyword EQUONLY takes effect only the first time that the macro is
included.
To allow more than one instance of a structure to be declared, the macro that
generates the structure prefixes the name of each field with a user-specifiable string
and an underscore character (_).
Specify the string when you invoke the macro. If you do not specify a string, the
macro uses the name of the structure to construct the prefix:
* Declare two object descriptors
CMQODA Prefix used="MQOD_" (the default)
MY_MQOD CMQODA Prefix used="MY_MQOD_"
The macros can generate structure declarations in one of two forms, controlled by
the DSECT parameter:
You can specify the value to be used to initialize a field in a structure by coding
the name of that field (without the prefix) as a parameter on the macro invocation,
accompanied by the value required.
If you specify a named constant (or equate) as a value on the macro invocation,
use the CMQA macro to define the named constant. You must not enclose in single
quotation marks (‘ ’) values that are character strings.
WebSphere MQ uses its structures for both input and output. If you want your
program to remain reenterable:
1. Define working storage versions of the structures as DSECTs, or define the
structures inline within an already-defined DSECT. Then copy the DSECT to
storage that is obtained using:
v For batch and TSO programs, the STORAGE or GETMAIN z/OS assembler
macros
v For CICS, the working storage DSECT (DFHEISTG) or the EXEC CICS
GETMAIN command
To correctly initialize these working storage structures, copy a constant version
of the corresponding structure to the working storage version.
Note: The MQMD and MQXQH structures are each more than 256 bytes long.
To copy these structures to storage, use the MVCL assembler instruction.
2. Reserve space in storage by using the LIST form (MF=L) of the CALL macro.
When you use the CALL macro to make an MQI call, use the EXECUTE form
(MF=E) of the macro, using the storage reserved earlier, as shown in the example
under “Using CEDF.” For more examples of how to do this, see the assembler
language sample programs as shipped with WebSphere MQ.
Use the assembler language RENT option to help you to determine if your
program is reenterable.
Using CEDF:
Coding in RPG
Supported only on WebSphere MQ for i5/OS.
In this book, the parameters of calls, the names of data types, the fields of
structures, and the names of constants are described using their long names. In
RPG, these names are abbreviated to six or fewer uppercase characters. For
Coding in PL/I
PL/I is supported on z/OS only.
Note the information in the following sections when coding WebSphere MQ for
z/OS programs in PL/I.
Structures:
Structures are declared with the BASED attribute, and so do not occupy any
storage unless the program declares one or more instances of a structure.
An instance of a structure can be declared using the like attribute, for example:
dcl my_mqmd like MQMD; /* one instance */
dcl my_other_mqmd like MQMD; /* another one */
The structure fields are declared with the INITIAL attribute; when the like
attribute is used to declare an instance of a structure, that instance inherits the
initial values defined for that structure. You need to set only those fields where the
value required is different from the initial value.
PL/I is not sensitive to case, and so the names of calls, structure fields, and
constants can be coded in lowercase, uppercase, or mixed case.
Named constants:
The named constants are declared as macro variables; as a result, named constants
that are not referred to by the program do not occupy any storage in the compiled
procedure.
However, the compiler option that causes the source to be processed by the macro
preprocessor must be specified when the program is compiled.
All the macro variables are character variables, even the ones that represent
numeric values. Although this might seem counter intuitive, it does not result in
any data-type conflict after the macro variables have been substituted by the macro
processor, for example:
%dcl MQMD_STRUC_ID char;
%MQMD_STRUC_ID = ’’’MD ’’’;
Visual Basic does not have a pointer datatype, so references to other WebSphere
MQ data structures are by offset rather than pointer. Declare a compound structure
consisting of the two component structures, and specify the compound structure
on the call. WebSphere MQ support for Visual Basic provides an MQCONNXAny
call to make this possible and allow client applications to specify the channel
properties on a client connection. It accepts an untyped structure (MQCNOCD) in
place of the usual MQCNO structure.
In general, UNIX and i5/OS systems have moved from a nonthreaded (process)
environment to a multithreaded environment. In the nonthreaded environment,
some functions could be implemented only by using signals, though most
applications did not need to be aware of signals and signal handling. In the
multithreaded environment, thread-based primitives support some of the functions
that used to be implemented in the nonthreaded environments using signals.
In many instances, signals and signal handling, although supported, do not fit well
into the multithreaded environment and various restrictions exist. This can be
particularly problematic when you are integrating application code with different
middleware libraries (running as part of the application) in a multithreaded
environment where each is trying to handle signals. The traditional approach of
saving and restoring signal handlers (defined per process), which worked when
there was only one thread of execution within a process, does not work in a
multithreaded environment. This is because many threads of execution could be
trying to save and restore a process-wide resource, with unpredictable results.
Unthreaded applications
(Not applicable on Solaris as all applications are considered threaded even if they
use only a single thread.)
Each MQI function sets up its own signal handler for the signals:
SIGALRM
SIGBUS
SIGFPE
SIGSEGV
SIGILL
Users’ handlers for these are replaced for the duration of the MQI function call.
Other signals can be caught in the normal way by user-written handlers. If you do
not install a handler, the default actions (for example, ignore, core dump, or exit)
are left in place.
Threaded applications
A thread is considered to be connected to WebSphere MQ from MQCONN (or
MQCONNX) until MQDISC.
Synchronous signals:
UNIX safely allows the setting up of a signal handler for such signals for the
whole process. However, WebSphere MQ sets up its own handler for the following
signals, in the application process, while any thread is connected to WebSphere
MQ:
SIGBUS
If you are writing multithreaded applications, there is only one process-wide signal
handler for each signal. When WebSphere MQ sets up its own synchronous signal
handlers it saves any previously registered handlers for each signal. After
WebSphere MQ handles one of the signals listed above, WebSphere MQ attempts
to call the signal handler that was in effect at the time of the first WebSphere MQ
connection within the process. The previously-registered handlers are restored
when all application threads have disconnected from WebSphere MQ.
Because signal handlers are saved and restored by WebSphere MQ, application
threads ideally should not establish signal handlers for these signals while there is
any possibility that another thread of the same process is also connected to
WebSphere MQ.
When establishing and restoring signal handlers, the general principle is that the
last signal handler to be saved must be the first to be restored:
v When an application establishes a signal handler after connecting to WebSphere
MQ, the previous signal handler must be restored before the application
disconnects from WebSphere MQ.
v When an application establishes a signal handler before connecting to
WebSphere MQ, the application must disconnect from WebSphere MQ before
restoring its signal handler.
Note: Failure to observe the general principle that the last signal handler to be
saved must be the first to be restored can result in unexpected signal handling in
the application and, potentially, the loss of signals by the application.
Asynchronous signals:
WebSphere MQ handles the following signals during I/O to a server. These signals
are defined by the communications stack. The application must not establish a
signal handler for these signals while a thread is connected to a queue manager:
SIGPIPE (for TCP/IP)
Additional considerations
Fastpath (trusted) applications:
If you try to call an MQI function from a signal handler while another MQI
function is active, MQRC_CALL_IN_PROGRESS is returned. If you try to call an
MQI function from a signal handler while no other MQI function is active, it is
likely to fail sometime during the operation because of the operating system
restrictions where only selective calls can be issued from, or within, a handler.
In the case of C++ destructor methods, which may be called automatically during
program exit, you might not be able to stop the MQI functions from being called.
Ignore any errors about MQRC_CALL_IN_PROGRESS. If a signal handler calls
exit(), WebSphere MQ backs out uncommitted messages in syncpoint as usual and
closes any open queues.
MQI functions do not return the code EINTR or any equivalent to application
programs.
If a signal occurs during an MQI call, and the handler calls return, the call
continues to run as if the signal had not happened. In particular, MQGET cannot
be interrupted by a signal to return control immediately to the application. If you
want to break out of an MQGET, set the queue to GET_DISABLED; alternatively,
use a loop around a call to MQGET with a finite time expiry (MQGMO_WAIT
with gmo.WaitInterval set), and use your signal handler (in a nonthreaded
environment) or equivalent function in a threaded environment to set a flag which
breaks the loop.
User exits and installable services that run as part of a WebSphere MQ process in a
multithreaded environment have the same restrictions as for fastpath applications.
They should be considered as permanently connected to WebSphere MQ and so do
not use signals or non-threadsafe operating system calls.
Users can install exit handlers for an MQ application using the SYS$DCLEXH
system service.
The exit handler receives control when an image exits. An image exit will normally
occur when you call the Exit ($EXIT) or Force Exit ($FORCEX) service. The
If you call an MQI function from within an exit handler, the behavior of the
function depends on the way the image was terminated. If the image was
terminated while another MQI function is active, an MQRC_CALL_IN_PROGRESS will be
returned.
It is possible to call an MQI function from within an exit handler if no other MQI
function is active and upcalls are disabled for the MQ application. If upcalls are
enabled for the MQ application, it will fail with the reason code MQRC_HCONN_ERROR.
The scope of an MQCONN or MQCONNX call is usually the thread that issued it.
If upcalls are enabled, the exit handler will be run as a separate thread and the
connection handles can not be shared.
Exit handlers are invoked within the interrupted context of the target process. It is
up to the application to ensure that actions taken by a handler are safe and
reliable, for the asynchronously interrupted context they are called from.
The way that this connection is made depends on the platform and the
environment in which the program is operating:
z/OS batch, WebSphere MQ for i5/OS, WebSphere MQ on UNIX systems, and
WebSphere MQ for Windows
Programs that run in these environments can use the MQCONN MQI call
to connect to, and the MQDISC call to disconnect from, a queue manager.
Alternatively, programs can use the MQCONNX call. This chapter
describes how to use these calls.
z/OS batch programs can connect, consecutively or concurrently, to
multiple queue managers on the same TCB.
IMS The IMS control region is connected to one or more queue managers when
it starts. This connection is controlled by IMS commands. (For information
on how to control the IMS adapter of WebSphere MQ for z/OS, see the
WebSphere MQ for z/OS System Administration Guide.) However, writers of
message queuing IMS programs must use the MQCONN MQI call to
specify the queue manager to which they want to connect. They can use
the MQDISC call to disconnect from that queue manager. This chapter
describes how writers of such programs should use these calls.
Before the IMS adapter processes a message for another user following a
Get Unique call from the IOPCB, or one implied by a checkpoint call, the
adapter ensures that the application closes handles and disconnects from
the queue manager.
IMS programs can connect, consecutively or concurrently, to multiple
queue managers on the same TCB.
CICS Transaction Server for OS/390® and CICS for MVS/ESA™
CICS programs do not need to do any work to connect to a queue
Note: CICS programs can also use the MQI connect and disconnect calls
(MQCONN and MQDISC). You might want to do this so that you can port
these applications to non-CICS environments with a minimum of recoding.
However, these calls always complete successfully in a CICS environment.
This means that the return code might not reflect the true state of the
connection to the queue manager.
TXSeries for Windows and Open Systems
These programs do not need to do any work to connect to a queue
manager because the CICS system itself is connected. Therefore, only one
connection at a time is supported. CICS applications must issue an
MQCONN call to obtain a connection handle, and an MQDISC call before
they exit.
Alternatively, in the z/OS MVS™ batch, TSO, and RRS environments you can
connect to any one queue manager within a queue-sharing group. The MQCONN
or MQCONNX request selects any one of the active members of the group.
The queue manager that you connect to must be local to the task. This means that
it must belong to the same system as the WebSphere MQ application.
In the IMS environment, the queue manager must be connected to the IMS control
region and to the dependent region that the program uses. The default queue
manager is specified in the CSQQDEFV module when WebSphere MQ for z/OS is
installed.
With the TXSeries CICS environment, and TXSeries for Windows and AIX, the
queue manager must be defined as an XA resource to CICS.
If the reason code indicates that the application is already connected to that queue
manager, the connection handle that is returned is the same as the one that was
returned when the application first connected. The application should not issue the
MQDISC call in this situation because the calling application will expect to remain
connected.
The scope of the connection handle is the same as that of the object handle (see
“Opening objects using the MQOPEN call” on page 100).
Descriptions of the parameters are given in the description of the MQCONN call in
the WebSphere MQ Application Programming Reference.
The MQCONN call fails if the queue manager is in a quiescing state when you
issue the call, or if the queue manager is shutting down.
That is, the connection handle returned from the call is valid only within the
thread that issued the call. Only one call can be made at any one time using the
handle. If it is used from a different thread, it is rejected as invalid. If you have
multiple threads in your application and each wants to use WebSphere MQ calls,
each one must issue MQCONN or MQCONNX. Alternatively, consider “Shared
(thread independent) connections with MQCONNX” on page 96.1
If your application is running as a client, it can connect to more than one queue
manager within a thread.
1. When using multithreaded applications with WebSphere MQ on UNIX systems you need to ensure that the applications have a
sufficient stack size for the threads. You are recommended to use a stack size of 256KB, or larger, when multithreaded
applications are making MQI calls, either by themselves or, with other signal handlers (for example, CICS).
Note: This default maintains the integrity of the queue manager (that is, it
makes the queue manager immune to errant programs), but impairs the
performance of the MQI calls.
MQCNO_FASTPATH_BINDING
Trusted applications imply that the WebSphere MQ application and the local
queue manager agent become the same process. Because the agent process
no longer needs to use an interface to access the queue manager, these
applications become an extension of the queue manager. This is defined by
the MQCNO_FASTPATH_BINDING option on the MQCONNX call.
You need to link trusted applications to the threaded WebSphere MQ
libraries. For instructions on how to set up a WebSphere MQ application to
run as trusted, see the WebSphere MQ Application Programming Reference.
On z/OS these options are tolerated, but only a standard bound connection is
performed. MQCNO Version 3, for z/OS, allows four alternative options:
MQCNO_SERIALIZE_CONN_TAG_QSG
This allows an application to request that only one instance of an
application runs at any one time in a queue-sharing group. This is
achieved by registering the use of a connection tag, whose value is
specified or derived by the application. The tag is a 128 byte character
string specified in the Version 3 MQCNO.
MQCNO_RESTRICT_CONN_TAG_QSG
This is used where an application consists of more than one process (or a
TCB), each of which can connect to a queue manager. Connection is
permitted only if there is no current use of the tag, or the requesting
application is within the same processing scope. This is MVS address space
within the same queue-sharing group as the tag owner.
MQCNO_SERIALIZE_CONN_TAG_Q_MGR
This is similar to MQCNO_SERIALIZE_CONN_TAG_QSG, but only the
local queue manager is interrogated to see if the requested tag is already in
use.
MQCNO_RESTRICT_CONN_TAG_Q_MGR
This is similar to MQCNO_RESTRICT_CONN_TAG_QSG, but only the
local queue manager is interrogated to see if the requested tag is already in
use.
A connection handle (Hconn) is returned from the MQCONNX call in the usual
way. This can be used by subsequent MQI calls from any thread in the process,
associating those calls with the Hconn returned from the MQCONNX. MQI calls
using a single shared Hconn are serialized across threads.
While the Hconn is in use by any thread, access to the connection is unavailable to
other threads. In circumstances where it is acceptable that a thread waits for any
previous call from another thread to complete, use MQCONNX with the option
MQCNO_HANDLE_SHARE_BLOCK.
However this can cause difficulties. Suppose that in step 2 above, the thread issues
a get request that waits for messages that might not have yet arrived (a get with
wait). In this case, threads 2 and 3 are also left waiting (blocked) for as long as the
get request takes. If you prefer that your application is notified of calls that are
already running on the Hconn, use MQCONNX with the option
MQCNO_HANDLE_SHARE_NO_BLOCK.
As input to the MQDISC call, you must supply the connection handle (Hconn) that
was returned by MQCONN or MQCONNX when you connected to the queue
manager.
Except on CICS on z/OS, after MQDISC is called the connection handle (Hconn) is
no longer valid, and you cannot issue any further MQI calls until you call
MQCONN or MQCONNX again. MQDISC does an implicit MQCLOSE for any
objects that are still open using this handle.
If you use MQCONNX to connect on WebSphere MQ for z/OS, MQDISC also ends
the scope of the connection tag established by the MQCONNX. However, in a
CICS, IMS, or RRS application, if there is an active unit of recovery associated with
a connection tag, the MQDISC is rejected with a reason code of
MQRC_CONN_TAG_NOT_RELEASED.
Descriptions of the parameters are given in the description of the MQDISC call in
the WebSphere MQ Application Programming Reference.
In the normal course of events a job that has the authority to open or connect to a
WebSphere MQ object closes or disconnect from that object. Even if the authority
of a job that has connected to or opened a WebSphere MQ object is revoked, the
MQCLOSE and MQDISC calls are accepted.
Use the MQOPEN call to open the object, using the options of the call to specify
what you want to do with the object. The only exception is if you want to put a
single message on a queue, then close the queue immediately. In this case, you can
bypass the opening stage by using the MQPUT1 call (see “Putting one message on a
queue using the MQPUT1 call” on page 117).
Before you open an object using the MQOPEN call, you must connect your
program to a queue manager. This is explained in detail, for all environments, in
“Connecting to and disconnecting from a queue manager” on page 91.
There are four types of WebSphere MQ object that you can open:
v Queue
v Namelist
v Process definition
v Queue manager
You open all these objects in a similar way using the MQOPEN call. For more
information about WebSphere MQ objects, see “WebSphere MQ objects” on page
48.
You can open the same object more than once, and each time you get a new object
handle. You might want to browse messages on a queue using one handle, and
remove messages from the same queue using another handle. This saves using up
resources to close and reopen the same object. You can also open a queue for
browsing and removing messages at the same time.
Moreover, you can open multiple objects with a single MQOPEN and close them
using MQCLOSE. See “Distribution lists” on page 119 for information about how
to do this.
When you attempt to open an object, the queue manager checks that you are
authorized to open that object for the options that you specify in the MQOPEN
call.
Objects are closed automatically when a program disconnects from the queue
manager. In the IMS environment, disconnection is forced when a program starts
It is good programming practice to close objects you have opened. Use the
MQCLOSE call to do this.
This chapter introduces opening and closing WebSphere MQ objects, under these
headings:
v “Opening objects using the MQOPEN call”
v “Creating dynamic queues” on page 107
v “Opening remote queues” on page 107
v “Closing objects using the MQCLOSE call” on page 108
Descriptions of the parameters of the MQOPEN call are given in the WebSphere MQ
Application Programming Reference.
The following sections describe the information that you must supply as input to
MQOPEN.
For full details of the MQOD structure see MQOD - Object descriptor.
For information about using the MQOD structure for distribution lists, see “Using
the MQOD structure” on page 120 under “Distribution lists” on page 119.
Name resolution
How the MQOPEN call resolves queue and queue manager names.
Note: A Queue manager alias is a remote queue definition without an RNAME field.
When you open a WebSphere MQ queue, the MQOPEN call performs a name
resolution function on the queue name that you specify. This determines on which
queue the queue manager performs subsequent operations. This means that when
you specify the name of an alias queue or a remote queue in your object descriptor
(MQOD), the call resolves the name either to a local queue or to a transmission
queue. If a queue is opened for any type of input, browse, or set, it resolves to a
local queue if there is one, and fails if there is not one. It resolves to a nonlocal
queue only if it is opened for output only, inquire only, or output and inquire only.
See Table 5 for an overview of the name resolution process. The name that you
supply in ObjectQMgrName is resolved before that in ObjectName.
Table 5 also shows how you can use a local definition of a remote queue to define
an alias for the name of a queue manager. This allows you to select which
transmission queue is used when you put messages on a remote queue, so you
could, for example, use a single transmission queue for messages destined for
many remote queue managers.
To use the following table, first read down the two left-hand columns, under the
heading Input to MQOD, and select the appropriate case. Then read across the
corresponding row, following any instructions. Following the instructions in the
Resolved names columns, you can either return to the Input to MQOD columns
and insert values as directed, or you can exit the table with the results supplied.
For example, you might be required to input ObjectName.
Table 5. Resolving queue names when using MQOPEN
Input to MQOD Resolved names
ObjectQMgrName ObjectName ObjectQMgrName ObjectName Transmission queue
Blank or local queue Local queue Local queue manager Input Not applicable (local
manager with no ObjectName queue used)
CLUSTER
attribute
Blank queue manager Local queue Workload management Input SYSTEM.CLUSTER.
with CLUSTER selected cluster queue ObjectName TRANSMIT.QUEUE and
attribute manager or specific local queue used
cluster queue manager
selected on PUT SYSTEM.QSG.
TRANSMIT.QUEUE (see
note)
SYSTEM.QSG.
TRANSMIT.QUEUE (see
note)
Queue manager is not (Not resolved) ObjectQMgrName or Input SYSTEM.CLUSTER.
the name of any local specific cluster queue ObjectName TRANSMIT.QUEUE
object; cluster queue manager selected on PUT
managers or queue SYSTEM.QSG.
manager alias found TRANSMIT.QUEUE (see
note)
Queue manager is not (Not resolved) Input ObjectQMgrName Input DefXmitQName attribute
the name of any local ObjectName of the queue manager
object; no cluster objects where DefXmitQName is
found supported.
SYSTEM.QSG.
TRANSMIT.QUEUE (see
note)
Note: The SYSTEM.QSG.TRANSMIT.QUEUE is used if local and remote queue managers are in the same
queue-sharing group; intra-group queuing is enabled.
Note:
1. BaseQName is the name of the base queue from the definition of the alias queue.
2. RemoteQName is the name of the remote queue from the local definition of the
remote queue.
3. RemoteQMgrName is the name of the remote queue manager from the local
definition of the remote queue.
4. XmitQName is the name of the transmission queue from the local definition of
the remote queue.
5. When using WebSphere MQ for z/OS queue managers that are part of a
queue-sharing group (QSG), the name of the QSG can be used instead of the
local queue manager name in Table 5 on page 101.
6. In the ObjectName column of the table, CLUSTER refers to both the CLUSTER
and CLUSNL attributes of the queue.
Opening an alias queue also opens the base queue to which the alias resolves, and
opening a remote queue also opens the transmission queue. Therefore you cannot
delete either the queue that you specify or the queue to which it resolves while the
other one is open.
The resolved queue name and the resolved queue manager name are stored in the
ResolvedQName and ResolvedQMgrName fields in the MQOD.
To route all messages put to a queue using MQPUT to the same queue manager by
the same route, use the MQOO_BIND_ON_OPEN option on the MQOPEN call.
If the queue that you open is not a cluster queue, the MQOO_BIND_* options are
ignored. If you specify the name of the local queue manager in the MQOD, the
local instance of the cluster queue is selected. If the queue manager name is blank,
any instance can be selected. See WebSphere MQ Queue Manager Clusters for more
information.
To open a queue or topic to put messages on it, use the MQOO_OUTPUT option.
To open a queue so that you can browse the messages on it, use the MQOPEN call
with the MQOO_BROWSE option.
This creates a browse cursor that the queue manager uses to identify the next
message on the queue. For more information, see “Browsing messages on a queue”
on page 156.
Note:
1. You cannot browse messages on a remote queue; do not open a remote queue
using the MQOO_BROWSE option.
2. You cannot specify this option when opening a distribution list. For further
information about distribution lists, see “Distribution lists” on page 119.
Three options control the opening of a queue to remove messages from it.
You can use only one of them in any MQOPEN call. These options define whether
your program has exclusive or shared access to the queue. Exclusive access means
that, until you close the queue, only you can remove messages from it. If another
program attempts to open the queue to remove messages, its MQOPEN call fails.
Shared access means that more than one program can remove messages from the
queue.
The most advisable approach is to accept the type of access that was intended for
the queue when the queue was defined. The queue definition involved the setting
of the Shareability and the DefInputOpenOption attributes. To accept this access,
use the MQOO_INPUT_AS_Q_DEF option. Refer to Table 6 to see how the setting
of these attributes affects the type of access that you will be given when you use
this option.
Table 6. How queue attributes and options of the MQOPEN call affect access to queues
Queue attributes Type of access with MQOPEN options
Shareability DefInputOpenOption AS_Q_DEF SHARED EXCLUSIVE
SHAREABLE SHARED shared shared exclusive
SHAREABLE EXCLUSIVE exclusive shared exclusive
NOT_SHAREABLE* SHARED* exclusive exclusive exclusive
NOT_SHAREABLE EXCLUSIVE exclusive exclusive exclusive
Note: * Although you can define a queue to have this combination of attributes, the
default input open option is overridden by the shareability attribute.
Alternatively:
v If you know that your application can work successfully even if other programs
can remove messages from the queue at the same time, use the
MQOO_INPUT_SHARED option. Table 6 shows how, in some cases you will be
given exclusive access to the queue, even with this option.
v If you know that your application can work successfully only if other programs
are prevented from removing messages from the queue at the same time, use the
MQOO_INPUT_EXCLUSIVE option.
Note:
1. You cannot remove messages from a remote queue. Therefore you cannot open
a remote queue using any of the MQOO_INPUT_* options.
2. You cannot specify this option when opening a distribution list. For further
information, see “Distribution lists” on page 119.
To open a queue so that you can set its attributes, use the MQOO_SET option.
You cannot set the attributes of any other type of object (see “Inquiring about and
setting object attributes” on page 180).
Note: You cannot specify this option when opening a distribution list.
If you want to be able to associate context information with a message when you
put it on a queue, you must use one of the message context options when you
open the queue.
The options allow you to differentiate between context information that relates to
the user who originated the message, and that which relates to the application that
originated the message. Also, you can opt to set the context information when you
put the message on the queue, or you can opt to have the context taken
automatically from another queue handle.
For more information about the subject of message context, see “Message context”
on page 46.
When you attempt to open an object using the MQOPEN call, the queue manager
checks that you have the authority to open that object. If you are not authorized,
the call fails.
However, server programs might want the queue manager to check the
authorization of the user on whose behalf they are working, rather than the
server’s own authorization. To do this, they must use the
MQOO_ALTERNATE_USER_AUTHORITY option of the MQOPEN call, and
specify the alternate user ID in the AlternateUserId field of the MQOD structure.
Typically, the server would get the user ID from the context information in the
message it is processing.
In the CICS environment on z/OS, if you use the MQOPEN call when the queue
manager is in a quiescing state, the call always fails.
When you open a local, alias or model queue, the local queue is returned.
However, when you open a remote queue or cluster queue, the ResolvedQName and
ResolvedQMgrName fields of the MQOD structure are filled with the names of the
remote queue and remote queue manger found in the remote queue definition, or
with the chosen remote cluster queue.
For example, you could use a dynamic queue for your reply-to queue. You specify
the name of the reply-to queue in the ReplyToQ field of the MQMD structure when
you put a message on a queue (see “Defining messages using the MQMD
structure” on page 110).
To create a dynamic queue, you use a template known as a model queue, together
with the MQOPEN call. You create a model queue using the WebSphere MQ
commands or the operations and control panels. The dynamic queue that you
create takes the attributes of the model queue.
When you call MQOPEN, specify the name of the model queue in the ObjectName
field of the MQOD structure. When the call completes, the ObjectName field is set
to the name of the dynamic queue that is created. Also, the ObjectQMgrName field is
set to the name of the local queue manager.
You can specify the name of the dynamic queue that you create in three ways:
v Give the full name that you want in the DynamicQName field of the MQOD
structure.
v Specify a prefix (fewer than 33 characters) for the name, and allow the queue
manager to generate the rest of the name. This means that the queue manager
generates a unique name, but you still have some control (for example, you
might want each user to use a certain prefix, or you might want to give a special
security classification to queues with a certain prefix in their name). To use this
method, specify an asterisk (*) for the last non-blank character of the
DynamicQName field. Do not specify a single asterisk (*) for the dynamic queue
name.
v Allow the queue manager to generate the full name. To use this method, specify
an asterisk (*) in the first character position of the DynamicQName field.
For more information about these methods, see the description of the DynamicQName
field in the WebSphere MQ Application Programming Reference.
To open a remote queue, use the MQOPEN call as for a local queue. You can
specify the name of the queue as follows:
1. In the ObjectName field of the MQOD structure, specify the name of the remote
queue as known to the local queue manager.
Note: Set the ObjectQMgrName field to the name of the remote queue manager
(it cannot be left blank in this case).
Only local names are validated when you call MQOPEN; the last check is for the
existence of the transmission queue to be used.
Descriptions of the parameters of the MQCLOSE call are given in the WebSphere
MQ Application Programming Reference.
If you want to put a single message on a queue and close the queue immediately
afterwards, you can use the MQPUT1 call. MQPUT1 performs the same functions
as the following sequence of calls:
v MQOPEN
v MQPUT
v MQCLOSE
Generally however, if you have more than one message to put on the queue, it is
more efficient to use the MQPUT call. This depends on the size of the message and
the platform that you are working on.
If the call completes successfully, it also returns your options structure and your
message descriptor structure. The call modifies your options structure to show the
name of the queue and the queue manager to which the message was sent. If you
The following sections describe the information that you must supply as input to
the MQPUT call.
Specifying handles
For the connection handle (Hconn) in CICS on z/OS applications, you can specify
the constant MQHC_DEF_HCONN (which has the value zero), or you can use the
connection handle returned by the MQCONN or MQCONNX call. For other
applications, always use the connection handle returned by the MQCONN or
MQCONNX call.
Whatever environment you are working in, use the same queue handle (Hobj) that
is returned by the MQOPEN call.
If MQPRI_PRIORITY_AS_Q_DEF or MQPER_PERSISTENCE_AS_Q_DEF is
specified for the message and the queue is a cluster queue, the values used are
those of the queue to which the MQPUT resolves. If that queue is disabled for
MQPUT, the call will fail. See WebSphere MQ Queue Manager Clusters for more
information.
The following sections give you help on filling in the fields of this structure. There
is a description of the structure in the WebSphere MQ Application Programming
Reference.
The MQPMO can also accommodate fields required for distribution lists (see
“Distribution lists” on page 119). If you want to use this facility, Version 2 of the
MQPMO structure is used. This includes the following fields:
RecsPresent
This field contains the number of queues in the distribution list; that is, the
number of Put Message Records (MQPMR) and corresponding Response
Records (MQRR) present.
Note: If you are using MQPUT1, the number of Response Record Pointers
and Response Record Offsets must be zero.
For a full description of Put Message Records (MQPMR) and Response
Records (MQRR), see the WebSphere MQ Application Programming Reference.
PutMsgRecFields
This indicates which fields are present in each Put Message Record
(MQPMR). For a list of these fields, see “Using the MQPMR structure” on
page 123.
PutMsgRecOffset and PutMsgRecPtr
Pointers (typically in C) and offsets (typically in COBOL) are used to
address the Put Message Records (see “Using the MQPMR structure” on
page 123 for an overview of the MQPMR structure).
Use the PutMsgRecPtr field to specify a pointer to the first Put Message
Record, or the PutMsgRecOffset field to specify the offset of the first Put
Message Record. This is the offset from the start of the MQPMO.
Depending on the PutMsgRecFields field, enter a nonnull value for either
PutMsgRecOffset or PutMsgRecPtr.
ResponseRecOffset and ResponseRecPtr
You also use pointers and offsets to address the Response Records (see
“Using the MQRR structure” on page 122 for further information about
Response Records).
Use the ResponseRecPtr field to specify a pointer to the first Response
Record, or the ResponseRecOffset field to specify the offset of the first
Response Record. This is the offset from the start of the MQPMO structure.
Enter a nonnull value for either ResponseRecOffset or ResponseRecPtr.
To determine the value of this attribute, use the MQINQ call on the queue
manager object. For large messages, you can change this value.
For an MQPUT operation, the size of the message must be smaller than or equal to
the MaxMsgLength attribute of both the queue and the queue manager. The values of
these attributes are independent, but you are recommended to set the
MaxMsgLength of the queue to a value less than or equal to that of the queue
manager.
If your messages are of the maximum size allowed for these queues, the addition
of these headers means that the put operations fail because the messages are now
too big. To reduce the possibility of the put operations failing:
v Make the size of your messages smaller than the MaxMsgLength attribute of the
transmission and dead-letter queues. Allow at least the value of the
MQ_MSG_HEADER_LENGTH constant (more for large distribution lists).
v Make sure that the MaxMsgLength attribute of the dead-letter queue is set to the
same as the MaxMsgLength of the queue manager that owns the dead-letter
queue.
The attributes for the queue manager and the message queuing constants are
described in the WebSphere MQ Application Programming Reference.
For full details see the description of the Action field in the WebSphere MQ
Application Programming Reference. A message handle is not necessarily required in
order to put a message. Its purpose is to associate properties with a message, so it
is required only if you are using message properties.
For more information on using remote and transmission queues, see WebSphere MQ
Intercommunications.
To associate properties with a message, the message must have a message handle.
Create a message handle using the MQCRTMH function call. Call MQSETMP
specifying this message handle for each property you want to set. A sample
program, amqsstma.c, is provided to illustrate the use of MQSETMP.
If this is a new message, when you put it to a queue, using MQPUT or MQPUT1,
set the OriginalMsgHandle field in the MQPMO to the value of this message
handle, and set the MQPMO Action field to MQACTP_NEW (this is the default
value).
If this is a message you have previously retrieved, and you are now forwarding or
replying to it or sending a report in response to it, put the original message handle
in the OriginalMsgHandle field of the MQPMO and the new message handle in
the NewMsgHandle field. Set the Action field to MQACTP_FORWARD,
MQACTP_REPLY, or MQACTP_REPORT, as appropriate.
For more information about the message handle and Action fields, see the
WebSphere MQ Application Programming Reference.
If you have properties in an MQRFH2 header from a message you have previously
retrieved, you can convert them to message handle properties using the
MQBUFMH call.
If you want no context information associated with your message, use the
MQPMO_NO_CONTEXT option.
The following topics explain the use of identity context, user context and all
context.
Programs should change the origin context information each time that they change
the data. However, applications that want to change or set any context information
must have the appropriate level of authority. The queue manager checks this
authority when the applications open the queues; they must have authority to use
the appropriate context options for the MQOPEN call.
If your application gets a message, processes the data from the message, then puts
the changed data into another message (possibly for processing by another
application), the application must pass the identity context information from the
original message to the new message. You can allow the queue manager to create
the origin context information.
To save the context information from the original message, use the
MQOO_SAVE_ALL_CONTEXT option when you open the queue for getting the
message. This is in addition to any other options you use with the MQOPEN call.
Note, however, that you cannot save context information if you only browse the
message.
When an MQPUT or MQPUT1 takes place and the context is being passed, all
properties in the user context are passed from the retrieved message to the put
message. Any user context properties that the putting application has altered are
put with their original values. Any user context properties that the putting
application has deleted are restored in the put message. Any user context
properties that the putting application has added to the message are retained.
Follow the same procedure as for passing identity context, except that you use the
MQOPEN option MQOO_PASS_ALL_CONTEXT and the put-message option
MQPMO_PASS_ALL_CONTEXT.
Note: When you set some (but not all) of the identity context fields using the
MQOO_SET_IDENTITY_CONTEXT and MQPMO_SET_IDENTITY_CONTEXT
options, it is important to realize that the queue manager does not set any of the
other fields.
You do not need any special authority to set a property in the user context. User
context has no MQOO_SET_* or MQPMO_SET_* context options
If the call completes successfully, it also returns your options structure and your
message descriptor structure. The call modifies your options structure to show the
name of the queue and the queue manager to which the message was sent. If you
request that the queue manager generate a unique value for the identifier of the
message that you are putting (by specifying binary zero in the MsgId field of the
MQMD structure), the call inserts the value in the MsgId field before returning this
structure to you.
Note: You cannot use MQPUT1 with a model queue name; however, once a model
queue has been opened, you can issue an MQPUT1 to the dynamic queue.
Distribution lists
Not supported on WebSphere MQ for z/OS.
When an MQOPEN call is issued, generic information is taken from the Object
Descriptor (MQOD). If you specify MQOD_VERSION_2 in the Version field and a
value greater than zero in the RecsPresent field, the Hobj can be defined as a
handle of a list (of one or more queues) rather than of a queue. In this case,
specific information is given through the object records (MQORs), which give
details of destination (that is, ObjectName and ObjectQMgrName).
The object handle (Hobj) is passed to the MQPUT call, allowing you to put to a list
rather than to a single queue.
When a message is put on the queues (MQPUT), generic information is taken from
the Put Message Option structure (MQPMO) and the Message Descriptor
(MQMD). Specific information is given in the form of Put Message Records
(MQPMRs).
Response Records (MQRR) can receive a completion code and reason code specific
to each destination queue.
MQOpen
Put to distribution list
Key:
Figure 9. How distribution lists work. This diagram shows that one message is transmitted
through the channel and can be put on more than one remote queue.
Use the MQOD structure to identify the queues that you want to open.
The structure contains the destination queue and queue manager names. The
ObjectName and ObjectQMgrName fields in the MQOD are not used for distribution
lists. There must be one or more object records. If the ObjectQMgrName is left blank,
the local queue manager is used. See the WebSphere MQ Application Programming
Reference for further information about these fields.
However, this works correctly only if the MQOD structure and the array of
MQOR records are contiguous; if the compiler inserts skip bytes between the
MQOD and the MQOR array, these must be added to the value stored in
ObjectRecOffset.
Using ObjectRecOffset is recommended for programming languages that do not
support the pointer data type, or that implement the pointer data type in a way
that is not portable to different environments (for example, the COBOL
programming language).
v By using the pointer field ObjectRecPtr.
In this case, the application can declare the array of MQOR structures separately
from the MQOD structure, and set ObjectRecPtr to the address of the array. The
following illustrates this technique for the C programming language:
MQOD MyMqod;
MQOR MyMqor[100];
MyMqod.ObjectRecPtr = MyMqor;
Using ObjectRecPtr is recommended for programming languages that support
the pointer data type in a way that is portable to different environments (for
example, the C programming language).
These structures are destination specific; each Response Record contains a CompCode
and Reason field for each queue of a distribution list. You must use this structure
to enable you to distinguish where any problems lie.
MQOR MQRR
0 Q QMgr 0 CompCode Reason
Q QMgr CompCode Reason
n-1 Q QMgr n-1 CompCode Reason
Figure 10. Opening a distribution list in C. The MQOD uses pointers to the MQOR and MQRR structures.
0 x 0 n-1 y
MQOD 2 n offset offset Q QMgr Q QMgr Comp Comp
Code Reason Code R
x y
Figure 11. Opening a distribution list in COBOL. The MQOD uses offsets in COBOL.
You can specify the following options when opening a distribution list:
v MQOO_OUTPUT
v MQOO_FAIL_IF_QUIESCING (optional)
v MQOO_ALTERNATE_USER_AUTHORITY (optional)
v MQOO_*_CONTEXT (optional)
See “Opening and closing objects” on page 99 for a description of these options.
This structure is optional and gives destination-specific information for some fields
that you might want to identify differently from those already identified in the
MQMD.
This implies that MsgId and CorrelId are provided for each destination of a
distribution list. The Put Message Records are provided as an array.
Figure 12 on page 124 shows how you can put a message to a distribution list in C.
MQPMR MQRR
e.g. MsgId, CorrelId (depending
on f) CompCode Reason
CompCode Reason
CompCode Reason
Figure 12. Putting a message to a distribution list in C. The MQPMO uses pointers to the MQPMR and MQRR
structures.
Figure 13 shows how you can put a message to a distribution list in COBOL.
x y
MQPMO 2 f n offset1 offset2 MQPMR MQRR
x y
Figure 13. Putting a message to a distribution list in COBOL. The MQPMO uses offsets in COBOL.
Using MQPUT1:
The queue manager marks the object handle as being no longer valid. This also
happens if the changes are made while an MQPUT1 call is being processed, or if
the changes apply to any queue to which the queue name resolves. The attributes
that affect the handle in this way are listed in the description of the MQOPEN call
in the WebSphere MQ Application Programming Reference. If your call returns the
MQRC_OBJECT_CHANGED reason code, close the queue, reopen it, then try to
put a message again.
If put operations are inhibited for a queue on which you are attempting to put
messages (or any queue to which the queue name resolves), the MQPUT or
MQPUT1 call fails and returns the MQRC_PUT_INHIBITED reason code. You
might be able to put a message successfully if you attempt the call at a later time,
if the design of the application is such that other programs change the attributes of
queues regularly.
Furthemore, if the queue that you are trying to put your message on is full, the
MQPUT or MQPUT1 call fails and returns MQRC_Q_FULL.
When you use distribution lists to put messages to multiple destinations, the
Response Records contain the specific CompCode and Reason for each destination. If
you receive a completion code of MQCC_FAILED, no message is put on any
destination queue successfully. If the completion code is MQCC_WARNING, the
message is successfully put on one or more of the destination queues. If you
receive a return code of MQRC_MULTIPLE_REASONS, the reason codes are not
all the same for every destination. Therefore, it is recommended to use the MQRR
structure so that you can determine which queue or queues caused an error and
the reasons for each.
When you have opened the queue, you can use the MQGET call repeatedly to
browse or remove messages on the same queue. Call MQCLOSE when you have
finished getting all the messages that you want from the queue.
This chapter introduces getting messages from a queue, under these headings:
v “Getting messages from a queue using the MQGET call”
v “The order in which messages are retrieved from a queue” on page 131
v “Getting a particular message” on page 138
v “Type of index” on page 142
v “Handling messages greater than 4 MB long” on page 143
v “Waiting for messages” on page 149
v “Signaling” on page 150
v “Skipping backout” on page 152
v “Application data conversion” on page 154
v “Browsing messages on a queue” on page 156
v “Browsing messages in logical order” on page 159
v “Some cases where the MQGET call fails” on page 162
The following sections describe the information you must supply as input to the
MQGET call.
Use the queue handle (Hobj) that is returned when you call MQOPEN.
If you know which message you want to get from the queue, see “Getting a
particular message” on page 138.
If you do not specify a particular message, MQGET retrieves the first message in
the queue. “The order in which messages are retrieved from a queue” on page 131
describes how the priority of a message, the MsgDeliverySequence attribute of the
queue, and the MQGMO_LOGICAL_ORDER option determine the order of the
messages in the queue.
However, if you want to group your messages, the GroupId must be the same for
messages in the same group, so that the call looks for a message having the same
identifiers as the previous message in order to make up the whole group.
When you have associated the message properties with the message handle, you
can return each property to your application using MQINQMP. A sample program,
amqsiqma.c, is provided to illustrate the use of MQINQMP.
You should normally return properties using a message handle. If you already use
properties in MQRFH2 headers in applications using earlier versions of WebSphere
MQ, you can continue to do so by using
Priority
A program can assign a priority to a message when it puts the message on a queue
(see “Message priorities” on page 26). Messages of equal priority are stored in a
queue in order of arrival, not the order in which they are committed.
The queue manager maintains queues either in strict FIFO (first in, first out)
sequence, or in FIFO within priority sequence. This depends on the setting of the
MsgDeliverySequence attribute of the queue. When a message arrives on a queue, it
is inserted immediately following the last message that has the same priority.
Programs can either get the first message from a queue, or they can get a
particular message from a queue, ignoring the priority of those messages. For
example, a program might want to process the reply to a particular message that it
sent earlier. For more information, see “Getting a particular message” on page 138.
If these conditions are not met, and the applications depend on the messages being
retrieved in a certain order, the applications must either include sequencing
information in the message data, or establish a means of acknowledging receipt of
a message before the next one is sent.
On WebSphere MQ for z/OS, you can use the queue attribute, IndexType, to
increase the speed of MQGET operations on the queue. For more information, see
“Type of index” on page 142.
Physical order is the order in which messages arrive on a queue. Logical order is
when all of the messages and segments within a group are in their logical
sequence, adjacent to each other, in the position determined by the physical
position of the first item belonging to the group.
For example, the logical order might look like Figure Figure 14:
Y1
Y2
Y3 (last)
Y3.1
Y3.2
Z1
Z2 (last)
B
The physical order, however, might be entirely different. As stated in topic “Logical
and physical ordering” on page 131, the physical position of the first item within
each group determines the logical position of the whole group. For example, if
groups Y and Z arrived at similar times, and message 2 of group Z overtook
message 1 of the same group, the physical order would look like Figure Figure 15
on page 133:
Y1
Z2 (last)
Y2
Y3 (last)
Y3.1
Y3.2
Z1
Note: On WebSphere MQ for z/OS, the physical order of messages on the queue
is not guaranteed if the queue is indexed by GROUPID.
Note: Take special care if you use an MQGET call to browse beyond the end of a
message group (or logical message not in a group) without specifying
MQGMO_LOGICAL_ORDER. For example, if the last message in the group
precedes the first message in the group on the queue, using
MQGMO_BROWSE_NEXT to browse beyond the end of the group, specifying
MQMO_MATCH_MSG_SEQ_NUMBER with MsgSeqNumber set to 1 (to find the first
message of the next group) returns again the first message in the group already
browsed. This could happen immediately, or a number of MQGET calls later (if
there are intervening groups).
Avoid the possibility of an infinite loop by opening the queue twice for browse:
v Use the first handle to browse only the first message in each group.
v Use the second handle to browse only the messages within a specific group.
v Use the MQMO_* options to move the second browse cursor to the position of
the first browse cursor, before browsing the messages in the group.
v Do not use the MQGMO_BROWSE_NEXT browse beyond the end of a group.
For further information about this, see the WebSphere MQ Application Programming
Reference.
For most applications you will probably choose either logical or physical ordering
when browsing. However, if you want to switch between these modes, remember
that when you first issue a browse with MQGMO_LOGICAL_ORDER, your
position within the logical sequence is established.
If the first item within the group is not present at this time, the group that you are
in is not considered to be part of the logical sequence.
Once the browse cursor is within a group, it can continue within the same group,
even if the first message is removed. Initially though, you can never move into a
group using MQGMO_LOGICAL_ORDER where the first item is not present.
There are two main reasons for using logical messages in a group:
v You might need to process the messages in a particular order
v You might need to process each message in a group in a related way.
In either case, retrieve the entire group with the same getting application instance.
For example, assume that the group consists of four logical messages. The putting
application looks like this:
PMO.Options = MQPMO_LOGICAL_ORDER | MQPMO_SYNCPOINT
MQCMIT
The getting application chooses not to start processing any group until all the
messages within it have arrived. specify MQGMO_ALL_MSGS_AVAILABLE for
the first message in the group; the option is ignored for subsequent messages
within the group.
MQCMIT
In the previous case, messages or segments cannot start to leave the node (if its
destination is remote) or start to be retrieved until the whole group has been put
and the unit of work is committed. This might not be what you want if it takes a
long time to put the whole group, or if queue space is limited on the node. To
overcome this, put the group in several units of work.
If the group is put within multiple units of work, it is possible for some of the
group to commit even when the putting application fails. The application must
therefore save status information, committed with each unit of work, which it can
use after a restart to resume an incomplete group. The simplest place to record this
information is in a STATUS queue. If a complete group has been successfully put,
the STATUS queue is empty.
If segmentation is involved, the logic is similar. In this case, the StatusInfo must
include the Offset.
/* First UOW */
/* Last UOW */
MQPUT MD.MsgFlags = MQMF_MSG_IN_GROUP
MQPUT MD.MsgFlags = MQMF_MSG_IN_GROUP
MQPUT MD.MsgFlags = MQMF_LAST_MSG_IN_GROUP
MQGET (from STATUS queue) GMO.Options = MQGMO_SYNCPOINT
MQCMIT
If all the units of work have been committed, the entire group has been put
successfully, and the STATUS queue is empty. If not, the group must be resumed at
the point indicated by the status information. MQPMO_LOGICAL_ORDER cannot
be used for the first put, but can thereafter.
else
/* Group was terminated prematurely */
Set GroupId, MsgSeqNumber in MQMD to values from Status message
PMO.Options = MQPMO_SYNCPOINT
MQPUT MD.MsgFlags = MQMF_MSG_IN_GROUP
From the getting application, you might want to start processing the messages in a
group before the whole group has arrived. This improves response times on the
messages within the group, and also means that storage is not required for the
entire group.
For recovery reasons, you must retrieve each message within a unit of work.
However, in order to realize the above benefits, use several units of work for each
group of messages.
Note: For intermediate units of work, you can avoid the MQGET calls from the
STATUS queue by specifying that each MQPUT to the status queue is a segment of
a message (that is, by setting the MQMF_SEGMENT flag), instead of putting a
complete new message for each unit of work. In the last unit of work, a final
During restart processing, instead of using a single MQGET to get a possible status
message, browse the status queue with MQGMO_LOGICAL_ORDER until you
reach the last segment (that is, until no further segments are returned). In the first
unit of work after restart, also specify the offset explicitly when putting the status
segment.
if ( msgs > 0 )
/* Come here if there was only 1 message in the group */
MQCMIT
If all the units of work have been committed, the entire group has been retrieved
successfully, and the STATUS queue is empty. If not, the group must be resumed at
the point indicated by the status information. MQGMO_LOGICAL_ORDER cannot
be used for the first retrieve, but can thereafter.
else
/* Group was terminated prematurely */
To get a particular message from a queue, use the MsgId and CorrelId fields of the
MQMD structure. However, applications can explicitly set these fields, so the
values that you specify might not identify a unique message. Table 7 shows which
message is retrieved for the possible settings of these fields. These fields are
ignored on input if you specify MQGMO_MSG_UNDER_CURSOR in the
GetMsgOpts parameter of the MQGET call.
Table 7. Using message and correlation identifiers
To retrieve ... MsgId CorrelId
First message in the queue MQMI_NONE MQCI_NONE
First message that matches MsgId Nonzero MQCI_NONE
First message that matches CorrelId MQMI_NONE Nonzero
First message that matches both MsgId and CorrelId Nonzero Nonzero
In each case, first means the first message that satisfies the selection criteria (unless
MQGMO_BROWSE_NEXT is specified, when it means the next message in the
sequence satisfying the selection criteria).
On return, the MQGET call sets the MsgId and CorrelId fields to the message and
correlation identifiers (respectively) of the message returned (if any).
138 WebSphere MQ: Application Programming Guide
If you set the Version field of the MQMD structure to 2, you can use the GroupId,
MsgSeqNumber, and Offset fields. Table 8 shows which message is retrieved for the
possible settings of these fields.
Table 8. Using the group identifier
To retrieve ... Match options
First message in the queue MQMO_NONE
First message that matches MsgId MQMO_MATCH_MSG_ID
First message that matches CorrelId MQMO_MATCH_CORREL_ID
First message that matches GroupId MQMO_MATCH_GROUP_ID
First message that matches MsgSeqNumber MQMO_MATCH_MSG_SEQ_NUMBER
First message that matches MsgToken MQMO_MATCH_MSG_TOKEN
First message that matches Offset MQMO_MATCH_OFFSET
Notes:
1. MQMO_MATCH_XXX implies that the XXX field in the MQMD structure is set to the
value to be matched.
2. The MQMO flags can be used in combination. For example,
MQMO_MATCH_GROUP_ID, MQMO_MATCH_MSG_SEQ_NUMBER, and
MQMO_MATCH_OFFSET can be used together to give the segment identified by the
GroupId, MsgSeqNumber, and Offset fields.
3. If you specify MQGMO_LOGICAL_ORDER, the message that you are trying to retrieve
is affected because the option depends on state information controlled for the queue
handle. For information about this, see “Logical and physical ordering” on page 131
and the WebSphere MQ Application Programming Reference.
The MQGET call usually retrieves the first message from a queue. If you specify a
particular message when you use the MQGET call, the queue manager has to
search the queue until it finds that message. This can affect the performance of
your application.
If you are using Version 2 or later of the MQGMO structure and do not specify the
MQMO_MATCH_MSG_ID or MQMO_MATCH_CORREL_ID flags, you do not
need to reset the MsgId or CorrelId fields respectively between MQGETs.
On WebSphere MQ for z/OS the queue attribute IndexType can be used to increase
the speed of MQGET operations on the queue. For more information, see “Type of
index” on page 142.
You can get a specific message from a queue by specifying its MsgToken and the
MatchOption MQMO_MATCH_MSG_TOKEN in the MQGMO structure. The
MsgToken is returned by the MQPUT call that originally put that message on the
queue, or by previous MQGET operations and remains constant unless the queue
manager is restarted.
If you are interested in only a subset of messages on the queue, you can specify
which messages you want to process by using a selection string with the
MQOPEN or MQSUB call. MQGET then retrieves the next message that satisfies
that selection string. For more information about selection strings, see “Selectors”
on page 32.
When read ahead is enabled, messages are sent to an in memory buffer on the
client called the read ahead buffer. The client will have a read ahead buffer for each
queue it has open with read ahead enabled. The messages in the read ahead buffer
are not persisted. The client periodically updates the server with information about
the amount of data it has consumed.
If a client application is restarted, messages in the read ahead buffer can be lost.
Using read ahead can improve performance when consuming non persistent
messages from a client application. This performance improvement is available to
both MQI and JMS applications. Client applications using MQGET or
asynchronous consumption will benefit from the performance improvements when
consuming non-persistent messages.
Not all client application designs are suited to using read ahead as not all options
are supported for use with read ahead and some options are required to be
consistent between MQGET calls when read ahead is enabled. If a client alters its
selection criteria between MQGET calls, messages being stored in the read ahead
buffer will remain stranded in the client read ahead buffer.
If a backlog of stranded messages with the previous selection criteria are no longer
required, a configurable purge interval can be set on the client to automatically
purge these messages from the client. The purge interval is one of a group of read
ahead tuning options determined by the client. It is possible to tune these options
to meet your requirements.
Read ahead is only performed for client bindings. The attribute is ignored for all
other bindings.
The following table indicates which options are supported for use with read ahead
and whether they can be altered between MQGET calls.
Table 9. MQGET options and read ahead
Permitted when read ahead is enabled and can Permitted when read ahead is enabled but MQGET Options that are not permitted
be altered between MQGET calls cannot be altered between MQGET calls1 when read ahead is enabled2
MQGET MQMD values MsgId3 Encoding
CorrelId3 CodedCharSetId
MQGET MQGMO v MQGMO_NO_WAIT v MQGMO_SYNCPOINT_IF _PERSISTENT v MQGMO_SET_SIGNAL
Options
v MQGMO_BROWSE_MESSAGE v MQGMO_NO_SYNCPOINT v MQGMO_SYNCPOINT
_UNDER_CURSOR v MQGMO_ACCEPT_TRUNCATED _MSG v MQGMO_MARK_SKIP _BACKOUT
v MQGMO_BROWSE_FIRST v MQGMO_CONVERT v MQGMO_MSG_UNDER _CURSOR4
v MQGMO_BROWSE_NEXT v MQGMO_LOCK
v MQGMO_FAIL_IF_QUIESCING
v MQGMO_UNLOCK
v MQGMO_LOGICAL_ORDER
v MQGMO_COMPLETE_MSG
v MQGMO_ALL_MSGS_AVAILABLE
v MQGMO_ALL_SEGMENTS_ AVAILABLE
Notes:
1. If these options are altered between MQGET calls an
MQRC_OPTIONS_CHANGED reason code will be returned.
2. If these options are specified on the first MQGET call then read ahead will be
disabled. If these options are specified on a subsequent MQGET call a reason
code MQRC_OPTIONS_ERROR will be returned.
3. The client applications needs to be aware that if the MsgId and CorrelId values
are altered between MQGET calls messages with the previous values may have
already been sent to the client and will remain in the client read ahead buffer
until consumed (or automatically purged).
4. MQGMO_MSG_UNDER_CURSOR is not possible with read ahead. Read ahead
is disabled when both MQOO_BROWSE and one of the
MQOO_INPUT_SHARED or MQOO_INPUT_EXCLUSIVE options are specified
when opening the queue.
If a client alters its selection criteria between MQGET calls, messages being stored
in the read ahead buffer that match the initial selection criteria will not be
consumed by the client application and remain stranded in the client read ahead
buffer. In situations where the client read ahead buffer contains a large number of
stranded messages the benefits associated with read ahead will be lost and a
separate request to the server required for each message consumed. To determine
whether read ahead is being used efficiently you can use the connection status
parameter, READA.
If you decide that because of these restrictions on MQGET, that a client application
design is not suited to read ahead, specify the MQOPEN option
MQOO_READ_AHEAD_NO. Alternatively set the default read ahead value of the
queue being opened altered to either NO or DISABLED.
If a client application design is not suited to read ahead you can disable it:
v at the queue level by setting the queue attribute, DEFREADA to NO if you do
not want read ahead to be used unless it is requested by a client application, or
DISABLED if you do not want read ahead to be used regardless of whether read
ahead is required by a client application.
v at the application level by using the MQOO_NO_READ_AHEAD option on the
MQOPEN function call.
Two MQCLOSE options allow you to configure what happens to any messages
that are being stored in the read ahead buffer if the queue is closed.
v Use MQCO_IMMEDIATE to discard messages in the read ahead buffer.
v Use MQCO_QUIESCE to ensure that messages in the read ahead buffer are
consumed by the application before the queue is closed. When MQCLOSE with
the MQCO_QUIESCE is issued and there are messages remaining on the read
ahead buffer, MQRC_READ_AHEAD_MSGS will be returned with
MQCC_WARNING.
Type of index
Supported only on WebSphere MQ for z/OS.
The queue attribute, IndexType, specifies the type of index that the queue manager
maintains to increase the speed of MQGET operations on the queue.
Value Description
NONE No index is maintained. Use this when retrieving messages sequentially (see “Priority” on
page 131).
GROUPID An index of group identifiers is maintained. You must use this index type if you want logical
ordering of message groups (see “Logical and physical ordering” on page 131).
MSGID An index of message identifiers is maintained. Use this when retrieving messages using the
MsgId field as a selection criterion on the MQGET call (see “Getting a particular message” on
page 138).
MSGTOKEN An index of message tokens is maintained.
CORRELID An index of correlation identifiers is maintained. Use this when retrieving messages using
the CorrelId field as a selection criterion on the MQGET call (see “Getting a particular
message” on page 138).
For a full description of the IndexType attribute, see the WebSphere MQ Application
Programming Reference. For conditions needed to change the IndexType attribute, see
the WebSphere MQ Script (MQSC) Command Reference.
If you are handling large messages, you can alter these attributes independently.
You can set the queue manager attribute value between 32768 bytes and 100 MB;
you can set the queue attribute value between 0 and 100 MB.
After changing one or both of the MaxMsgLength attributes, restart your applications
and channels to ensure that the changes take effect.
When these changes are made, the message length must be less than or equal to
both the queue and the queue manager MaxMsgLength attributes. However, existing
messages might be longer than either attribute.
Message segmentation
Not supported in WebSphere MQ for z/OS.
The next sections look at common uses for segmenting messages. For putting and
destructively getting, it is assumed that the MQPUT or MQGET calls always
operate within a unit of work. We strongly recommend that you always use this
technique, to reduce the possibility of incomplete groups being present in the
network. Single-phase commit by the queue manager is assumed, but of course
other coordination techniques are equally valid.
The only changes necessary for these applications are for the putting application to
authorize the queue manager to perform segmentation if necessary:
PMO.Options = (existing options)
MQPUT MD.MsgFlags = MQMF_SEGMENTATION_ALLOWED
The application buffer must be large enough to contain the reassembled message
(unless you include the MQGMO_ACCEPT_TRUNCATED_MSG option).
Application segmentation:
MQCMIT
If you do not use MQPMO_LOGICAL_ORDER, the application must set the Offset
and the length of each segment. In this case, logical state is not maintained
automatically.
The getting application cannot guarantee to have a buffer large enough to hold any
reassembled message. It must therefore be prepared to process segments
individually.
For messages that are segmented, this application does not want to start processing
one segment until all the segments that constitute the logical message are present.
MQGMO_ALL_SEGMENTS_AVAILABLE is therefore specified for the first
segment. If you specify MQGMO_LOGICAL_ORDER and there is a current logical
message, MQGMO_ALL_SEGMENTS_AVAILABLE is ignored.
Once the first segment of a logical message has been retrieved, use
MQGMO_LOGICAL_ORDER to ensure that the remaining segments of the logical
message are retrieved in order.
MQCMIT
The messages must be maintained in logical order in a group, and some or all of
them might be so large that they require application segmentation.
In our example, a group of four logical messages is to be put. All but the third
message are large, and require segmentation, which is performed by the putting
application:
PMO.Options = MQPMO_LOGICAL_ORDER | MQPMO_SYNCPOINT
MQCMIT
MQCMIT
You can put and get a segmented message that spans a unit of work in a similar
way to “Putting and getting a group that spans units of work” on page 135.
Reference messages
Not supported in WebSphere MQ for z/OS.
This method allows a large object to be transferred from one node to another
without storing the object on WebSphere MQ queues at either the source or the
destination nodes. This is of particular benefit when the data already exists in
another form, for example, for mail applications.
To do this, you specify a message exit at both ends of a channel. For information
on how to do this, see WebSphere MQ Intercommunications.
Another message exit is configured at the receiving MCA. When this message exit
sees one of these messages, it creates the object using the object data that was
appended and passes on the reference message without it. The reference message
can now be received by an application and this application knows that the object
(or at least the portion of it represented by this reference message) has been
created at this node.
The maximum amount of object data that a sending message exit can append to
the reference message is limited by the negotiated maximum message length for
the channel. The exit can return only a single message to the MCA for each
message that it is passed, so the putting application can put several messages to
cause one object to be transferred. Each message must identify the logical length
and offset of the object that is to be appended to it. However, in cases where it is
not possible to know the total size of the object or the maximum size allowed by
the channel, design the sending message exit so that the putting application just
puts a single message, and the exit itself puts the next message on the transmission
queue when it has appended as much data as it can to the message it has been
passed.
Before using this method of dealing with large messages, consider the following:
v The MCA and the message exit run under a WebSphere MQ user ID. The
message exit (and therefore, the user ID) needs to access the object to either
retrieve it at the sending end or create it at the receiving end; this might only be
feasible in cases where the object is universally accessible. This raises a security
issue.
v If the reference message with bulk data appended to it must travel through
several queue managers before reaching its destination, the bulk data is present
on WebSphere MQ queues at the intervening nodes. However, no special
support or exits need to be provided in these cases.
Assuming that the object is 70 000 bytes long, the sending message exit sends the
first 40 000 bytes along the channel in a reference message containing:
v 40 000 bytes of physical data following the MQRMH
v DataLogicalLength = 40000
v DataLogicalOffset = 0 (from the start of the object).
When this message exit is seen by the sending message exit, the remaining 30,000
bytes of data is appended, and the fields are set to:
v 30,000 bytes of physical data following the MQRMH
v DataLogicalLength = 30000
v DataLogicalOffset = 40000 (starting from this point).
For a description of the sample programs provided for the use of reference
messages, see “Sample programs (all platforms except z/OS)” on page 395.
If the message does not arrive within this time, the MQGET call completes with
the MQRC_NO_MSG_AVAILABLE reason code.
You can specify an unlimited wait interval using the constant MQWI_UNLIMITED
in the WaitInterval field. However, events outside your control could cause your
program to wait for a long time, so use this constant with caution. IMS
applications must not specify an unlimited wait interval because this would
prevent the IMS system terminating. (When IMS terminates, it requires all
dependent regions to end.) Instead, IMS applications can specify a finite wait
interval; then, if the call completes without retrieving a message after that interval,
issue another MQGET call with the wait option.
Note: If more than one program is waiting on the same shared queue to remove a
message, only one program is activated by a message arriving. However, if more
than one program is waiting to browse a message, all the programs can be
activated. For more information, see the description of the Options field of the
MQGMO structure in the WebSphere MQ Application Programming Reference.
If the state of the queue or the queue manager changes before the wait interval
expires, the following actions occur:
v If the queue manager enters the quiescing state, and you used the
MQGMO_FAIL_IF_QUIESCING option, the wait is canceled and the MQGET
call completes with the MQRC_Q_MGR_QUIESCING reason code. Without this
option, the call remains waiting.
v On z/OS, if the connection (for a CICS or IMS application) enters the quiescing
state, and you used the MQGMO_FAIL_IF_QUIESCING option, the wait is
canceled and the MQGET call completes with the MQRC_CONN_QUIESCING
reason code. Without this option, the call remains waiting.
v If the queue manager is forced to stop, or is canceled, the MQGET call completes
with either the MQRC_Q_MGR_STOPPING or the
MQRC_CONNECTION_BROKEN reason code.
If you want your application to wait on more than one queue, use the signal
facility of WebSphere MQ for z/OS (see “Signaling”). For more information about
the circumstances in which these actions occur, see the WebSphere MQ Application
Programming Reference.
Signaling
Signaling is supported only on WebSphere MQ for z/OS.
Signaling is an option on the MQGET call to allow the operating system to notify
(or signal) a program when an expected message arrives on a queue. This is similar
to the get with wait function described in topic “Waiting for messages” on page 149
because it allows your program to continue with other work while waiting for the
signal. However, if you use signaling, you can free the application thread and rely
on the operating system to notify the program when a message arrives.
To set a signal
To set a signal, do the following in the MQGMO structure that you use on your
MQGET call:
1. Set the MQGMO_SET_SIGNAL option in the Options field.
2. Set the maximum life of the signal in the WaitInterval field. This sets the
length of time (in milliseconds) for which you want WebSphere MQ to monitor
the queue. Use the MQWI_UNLIMITED value to specify an unlimited life.
Note: IMS applications must not specify an unlimited wait interval because
this would prevent the IMS system from terminating. (When IMS terminates, it
requires all dependent regions to end.) Instead, IMS applications can examine
the state of the ECB at regular intervals (see step 3). A program can have
signals set on several queue handles at the same time:
3. Specify the address of the Event Control Block (ECB) in the Signal1 field. This
notifies you of the result of your signal. The ECB storage must remain available
until the queue is closed.
Note: You cannot use the MQGMO_SET_SIGNAL option in conjunction with the
MQGMO_WAIT option.
Note: Another application could get the message in the time between your
receiving the signal and issuing another MQGET call.
When a suitable message is already on the queue, the MQGET call completes in
the same way as an MQGET call without signaling. Also, if an error is detected
immediately, the call completes and the return codes are set.
If the program has no other work to do while it is waiting for the ECB to be
posted, it can wait for the ECB using:
v For a CICS Transaction Server for OS/390 program, the EXEC CICS WAIT
EXTERNAL command
v For batch and IMS programs, the z/OS WAIT macro
If the state of the queue or the queue manager changes while the signal is set (that
is, the ECB has not yet been posted), the following actions occur:
v If the queue manager enters the quiescing state, and you used the
MQGMO_FAIL_IF_QUIESCING option, the signal is canceled. The ECB is
posted with the MQEC_Q_MGR_QUIESCING completion code. Without this
option, the signal remains set.
v If the queue manager is forced to stop, or is canceled, the signal is canceled. The
signal is delivered with the MQEC_WAIT_CANCELED completion code.
v If the attributes of the queue (or a queue to which the queue name resolves) are
changed so that get requests are now inhibited, the signal is canceled. The signal
is delivered with the MQEC_WAIT_CANCELED completion code.
Note:
1. If more than one program has set a signal on the same shared queue to remove
a message, only one program is activated by a message arriving. However, if
more than one program is waiting to browse a message, all the programs can
be activated. The rules that the queue manager follows when deciding which
applications to activate are the same as those for waiting applications: for more
information, see the description of the Options field of the MQGMO structure
in the WebSphere MQ Application Programming Reference.
2. If there is more than one MQGET call waiting for the same message, with a
mixture of wait and signal options, each waiting call is considered equally. For
more information, see the description of the Options field of the MQGMO
structure in the WebSphere MQ Application Programming Reference.
3. Under some conditions, it is possible both for an MQGET call to retrieve a
message and for a signal (resulting from the arrival of the same message) to be
For information about how to set a signal, see the description of the
MQGMO_SET_SIGNAL option and the Signal1 field in the WebSphere MQ
Application Programming Reference.
Skipping backout
Supported only on WebSphere MQ for z/OS.
As part of a unit of work, an application program can issue one or more MQGET
calls to get messages from a queue. If the application program detects an error, it
can back out the unit of work. This restores all the resources updated during that
unit of work to the state that they were in before the unit of work started, and
reinstates the messages retrieved by the MQGET calls.
Once reinstated, these messages are available to subsequent MQGET calls issued
by the application program. In many cases, this does not cause a problem for the
application program. However, in cases where the error leading to the backout
cannot be circumvented, having the message reinstated on the queue can cause the
application program to enter an MQGET-error-backout loop.
The application program must issue a WebSphere MQ call either to commit the
new unit of work, or to back out the new unit of work. For example, the program
can perform exception handling, such as informing the originator that the message
has been discarded, and commit the unit of work so removing the message from
the queue, If the new unit of work is backed out (for any reason) the message is
reinstated on the queue.
Within a unit of work, there can be only one MQGET request marked as skipping
backout; however, there can be several other messages that are not marked as
skipping backout. Once a message has been marked as skipping backout, any
further MQGET calls within the unit of work that specify
MQGMO_MARK_SKIP_BACKOUT fail with reason code
MQRC_SECOND_MARK_NOT_ALLOWED.
Note:
1. The marked message skips backout only if the unit of work containing it is
terminated by an application request to back it out. If the unit of work is
backed out for any other reason, the message is backed out onto the queue in
the same way that it would be if it was not marked to skip backout.
2. Skip backout is not supported within DB2 stored procedures participating in
units of work controlled by RRS. For example, an MQGET call with the
MQGMO_MARK_SKIP_BACKOUT option will fail with the reason code
MQRC_OPTION_ENVIRONMENT_ERROR.
Step 1.
Initial processing, including
MQOPEN of queue specifying
one MQOO INPUT * option
START-OF-UOW1
Step 2.
MQGET message, specifying
MQGMO MARK SKIP BACKOUT
and MQGMO SYNCPOINT
Step 3.
Other resource updates made
for UOW1
Yes No
OK?
Step 4. Step 5.
Commit (message Application requests
removed from queue) backout
Step 6.
Updates from Step 3
backed out
END-OF-UOW1
START-OF-UOW2
Step 7.
Message retrieved at
Step 2 skips backout
and enters new unit
of work
Step 8.
Exception handling.
This must include a
WebSphere MQ operation
Yes No
OK?
END-OF-UOW2
When an application puts messages on a queue, the local queue manager adds
control information to the message descriptors to facilitate the control of the
messages when they are processed by queue managers and MCAs. Depending on
the environment, the message header data fields are created in the character set
and encoding of the local system.
When you move messages between systems, you sometimes need to convert the
application data into the character set and encoding required by the receiving
system. This can be done either from within application programs on the receiving
system or by the MCAs on the sending system. If data conversion is supported on
the receiving system, use application programs to convert the application data,
rather than depending on the conversion having already occurred at the sending
system.
Application data is converted within an application program when you specify the
MQGMO_CONVERT option in the Options field of the MQGMO structure passed
to an MQGET call, and all the following are true:
If the sending MCA is to convert the data, specify the CONVERT(YES) keyword on
the definition of each sender or server channel for which conversion is required. If
the data conversion fails, the message is sent to the DLQ at the sending queue
manager and the Feedback field of the MQDLH structure indicates the reason. If
the message cannot be put on the DLQ, the channel closes and the unconverted
message remains on the transmission queue. Data conversion within applications
rather than at sending MCAs avoids this situation.
As a general rule, data in the message that is described as character data by the
built-in format or data-conversion exit is converted from the coded character set
used by the message to that requested, and numeric fields are converted to the
encoding requested.
For further details of the conversion processing conventions used when converting
the built-in formats, and for information about writing your own data-conversion
exits, see “Writing data-conversion exits” on page 163. See also the WebSphere MQ
Application Programming Reference for information about the language support
tables and about the supported machine encodings.
The problem arises because the EBCDIC newline character is not converted
consistently across platforms or conversion tables. As a result, if the data is
displayed on an ASCII platform, the formatting might be incorrect. This would
make it difficult, for example, to administer an i5/OS system remotely from an
ASCII platform using RUNMQSC.
You can have more than one browse cursor active (from a single program) by
issuing several MQOPEN requests for the same queue.
When you call MQGET for browsing, use one of the following options in your
MQGMO structure:
MQGMO_BROWSE_FIRST
Gets a copy of the first message that satisfies the conditions specified in
your MQMD structure.
MQGMO_BROWSE_NEXT
Gets a copy of the next message that satisfies the conditions specified in
your MQMD structure.
MQGMO_BROWSE_MSG_UNDER_CURSOR
Gets a copy of the message currently pointed to by the cursor, that is, the
one that was last retrieved using either the MQGMO_BROWSE_FIRST or
the MQGMO_BROWSE_NEXT option.
When you open a queue, the browse cursor is positioned logically just before the
first message on the queue. This means that if you make your MQGET call
immediately after your MQOPEN call, you can use the MQGMO_BROWSE_NEXT
option to browse the first message; you do not have to use the
MQGMO_BROWSE_FIRST option.
The order in which messages are copied from the queue is determined by the
MsgDeliverySequence attribute of the queue. (For more information, see “The order
in which messages are retrieved from a queue” on page 131.)
The first message in a queue in this sequence is the message that has been on the
queue the longest.
The first message in a queue in this sequence is the message that has been on the
queue the longest and that has the highest priority at the time that the MQOPEN
call is issued.
The browse cursor points to the next message, working from the priority of the
first message to finish with the message at the lowest priority. It browses any
messages put to the queue during this time as long as they are of priority equal to,
or lower than, the message identified by the current browse cursor.
Any messages put to the queue of higher priority can be browsed only by:
v Opening the queue for browse again, at which point a new browse cursor is
established
v Using the MQGMO_BROWSE_FIRST option
Uncommitted messages:
If the message delivery sequence is changed from priority to FIFO while there are
messages on the queue, the order of the messages that are already queued is not
changed. Messages added to the queue subsequently take the default priority of
the queue.
When you browse an indexed queue that contains only messages of a single
priority (either persistent or nonpersistent or both), the queue manager performs
the browse by making use of the index, when any of the following forms of
browse are used:
1. If the queue is indexed by MSGID, and the above condition is true, browse
requests that pass a MSGID in the MQMD structure are processed using the
index to find the target message.
If the browse request does not pass a MSGID, CORRELID, or GROUPID in the
MQMD structure, the queue is indexed, and a message is returned, the index entry
for the message must be found, and information within it used to update the
browse cursor. If you use a wide selection of index values, this extra processing
adds little overhead to the browse request.
Note: If another program is likely to get the same message, consider using the
MQGMO_LOCK option as well. MQRC_TRUNCATED_MSG_ACCEPTED
should be returned.
2. Use the returned DataLength to allocate the storage needed.
3. Issue an MQGET with the MQGMO_BROWSE_MSG_UNDER_CURSOR.
The message pointed to is the last one that was retrieved; the browse cursor will
not have moved. You can choose either to lock the message using the
MQGMO_LOCK option, or to unlock a locked message using MQGMO_UNLOCK
option.
To remove the message, call MQGET again, but in the Options field of the
MQGMO structure, specify MQGMO_MSG_UNDER_CURSOR. In this case, the
MQGET call ignores the MsgId, CorrelId, and GroupId fields of the MQMD
structure.
In the time between your browsing and removal steps, another program might
have removed messages from the queue, including the message under your browse
cursor. In this case, your MQGET call returns a reason code to say that the
message is not available.
If an application browses through the various messages of one group (using logical
order), it is important that logical order should be followed to reach the start of the
next group, because the last message of one group might occur physically after the
first message of the next group. The MQGMO_LOGICAL_ORDER option ensures
that logical order is followed when scanning a queue.
and the same browse-next function is issued, it is not noticed that group 123 is
now complete, because the first message of this group is before the browse cursor.
In some cases (for example, if messages are retrieved destructively when the group
is present in its entirety), you can use MQGMO_ALL_MSGS_AVAILABLE together
with MQGMO_BROWSE_FIRST. Otherwise, you must repeat the browse scan to
take note of newly-arrived messages that have been missed; just issuing
MQGMO_WAIT together with MQGMO_BROWSE_NEXT and
MQGMO_ALL_MSGS_AVAILABLE does not take account of them. (This also
happens to higher-priority messages that might arrive after scanning the messages
is complete.)
The next sections look at browsing examples that deal with unsegmented
messages; segmented messages follow similar principles.
In this example, the application browses through each message on the queue, in
logical order.
Messages on the queue might be grouped. For grouped messages, the application
does not want to start processing any group until all the messages within it have
Chapter 2. Writing a WebSphere MQ application 159
arrived. MQGMO_ALL_MSGS_AVAILABLE is therefore specified for the first
message in the group; for subsequent messages in the group, this option is
unnecessary.
It is assumed that the application’s buffer is always large enough to hold the entire
message, whether or not the message has been segmented.
MQGMO_COMPLETE_MSG is therefore specified on each MQGET.
In this example, the application browses each of the logical messages within a
group, before deciding whether to retrieve that group destructively.
The first part of this example is similar to the previous one. However, in this case,
having browsed an entire group, we decide to go back and retrieve it destructively.
if ( GroupStatus == ’ ’ )
else
/* We retrieved one or more messages in a group. The browse cursor */
/* will not normally be still on the first in the group, so we have */
/* to match on the GroupId and MsgSeqNumber = 1. */
/* Another way, which works for both grouped and ungrouped messages,*/
/* would be to remember the MsgId of the first message when it was */
/* browsed, and match on that. */
GMO.Options = MQGMO_COMPLETE_MSG | MQGMO_SYNCPOINT
MQGET GMO.MatchOptions = MQMO_MATCH_GROUP_ID
| MQMO_MATCH_MSG_SEQ_NUMBER,
(MQMD.GroupId = value already in the MD)
MQMD.MsgSeqNumber = 1
/* Process first or only message */
...
If you browse messages on a queue, you might retrieve them in a different order to
the order in which you would retrieve them if you got them destructively. In
particular, you can browse the same message multiple times, which is not possible
if it is removed from the queue. To avoid this you can mark messages as they are
browsed, and avoid retrieving marked messages. This is sometimes referred to as
browse with mark. To mark browsed messages, use the get message option
MQGMO_MARK_BROWSE_HANDLE, and to retrieve only messages that are not
marked, use MQGMO_UNMARKED_BROWSE_MSG. If you use the combination
of options MQGMO_BROWSE_FIRST, MQGMO_UNMARKED_BROWSE_MSG,
and MQGMO_MARK_BROWSE_HANDLE, and issue repeated MQGETs, you will
retrieve each message on the queue in turn. This prevents repeated delivery of
messages even though MQGMO_BROWSE_FIRST is used to ensure that messages
are not skipped. This combination of options can be represented by the single
constant MQGMO_BROWSE_HANDLE. When there are no messages on the queue
that have not been browsed, MQRC_NO_MSG_AVAILABLE is returned.
If multiple applications are browsing the same queue, they can open the queue
with the options MQOO_CO_OP and MQOO_BROWSE. The object handle
returned by each MQOPEN is considered to be part of a cooperating group. Any
message returned by an MQGET call specifying the option
MQGMO_MARK_BROWSE_CO_OP is considered to be marked for this
cooperating set of handles.
If a message has been marked for some time, it can be automatically unmarked by
the queue manager and made available for browsing again. The queue manager
attribute MsgMarkBrowseInterval gives the time in milliseconds for which a
When the single process or set of cooperative processes marking messages stop,
any marked messages become unmarked.
Rather than multiple copies of the same dispatcher application, you might have a
number of different dispatcher applications browsing the queue, each suitable for
processing a subset of the messages on the queue. In each dispatcher, open the
queue with MQOO_CO_OP. This indicates that the dispatchers are cooperating and
will be aware of each other’s marked messages.
v If the order of message processing for a single dispatcher is important, each
dispatcher makes repeated MQGET calls, specifying the options
MQGMO_BROWSE_FIRST, MQGMO_UNMARKED_BROWSE_MSG , and
MQGMO_MARK_BROWSE_HANDLE (or MQGMO_BROWSE_HANDLE). If the
browsed message is suitable for this dispatcher to process, it then makes an
MQGET call specifying MQMO_MATCH_MSG_TOKEN,
MQGMO_MARK_BROWSE_CO_OP, and the MsgToken returned by the
previous MQGET call. If the call succeeds, the dispatcher initializes the
consumer, passing the MsgToken to it.
v If the order of message processing is not important and the dispatcher is
expected to process most of the messages it encounters, use the options
MQGMO_BROWSE_FIRST, MQGMO_UNMARKED_BROWSE_MSG , and
MQGMO_MARK_BROWSE_CO_OP (or MQGMO_BROWSE_CO_OP). If the
dispatcher browses a message it cannot process, it unmarks the message by
calling MQGET with the option MQMO_MATCH_MSG_TOKEN,
MQGMO_UNMARK_BROWSE_CO_OP, and the MsgToken returned previously.
If get operations are inhibited for a queue from which you are attempting to get
messages (or any queue to which the queue name resolves), the MQGET call fails
and returns the MQRC_GET_INHIBITED reason code. This happens even if you
are using the MQGET call for browsing. You might be able to get a message
successfully if you attempt the MQGET call at a later time, if the design of the
application is such that other programs change the attributes of queues regularly.
Control can be passed to the data-conversion exit during an MQGET call. This
avoids converting across different platforms before reaching the final destination.
However, if the final destination is a platform that does not support data
conversion on the MQGET, you must specify CONVERT(YES) on the sender
channel that sends the data to its final destination. This ensures that WebSphere
MQ converts the data during transmission. In this case, your data-conversion exit
must reside on the system where the sender channel is defined.
The MQGET call is issued directly by the application. Set the CodedCharSetId and
Encoding fields in the MQMD to the character set and encoding required. If your
application uses the same character set and encoding as the queue manager, set
CodedCharSetId to MQCCSI_Q_MGR, and Encoding to MQENC_NATIVE. After the
MQGET call completes, these fields have the values appropriate to the message
data returned. These might differ from the values required if the conversion was
not successful. Your application should reset these fields to the values required
before each MQGET call.
For a description of the parameters that are passed to the data-conversion exit, and
detailed usage notes, see the WebSphere MQ Application Programming Reference for
the MQ_DATA_CONV_EXIT call and the MQDXP structure.
Programs that convert application data between different machine encodings and
CCSIDs must conform to the WebSphere MQ data conversion interface (DCI).
There are some other conditions, described fully in the usage notes of the
MQ_DATA_CONV_EXIT call in the WebSphere MQ Application Programming
Reference.
See the WebSphere MQ Application Programming Reference for details of the MQGET
call. Data-conversion exits cannot use MQI calls, other than MQXCNVC.
To help you to create a data-conversion exit program, the following are supplied:
v A skeleton source file
v A convert characters call
Platform File
AIX amqsvfc0.c
i5/OS QMQMSAMP/QCSRC(AMQSVFC4)
HP-UX amqsvfc0.c
Linux amqsvfc0.c
Solaris amqsvfc0.c
No other MQI calls can be made from within the exit; an attempt to make such a
call fails with reason code MQRC_CALL_IN_PROGRESS.
The command for your platform produces a fragment of code that performs data
conversion on data type structures, for use in your data-conversion exit program.
The command takes a file containing one or more C language structure definitions.
On z/OS, it then generates a data set containing assembler code fragments and
conversion functions. On other platforms, it generates a file with a C function to
convert each structure definition. On z/OS, the utility requires access to the
LE/370 run-time library SCEERUN.
Figure 17 shows an example of the JCL used to invoke the CSQUCVX utility.
SYSPRINT This specifies a data set or print spool class for reports and error messages.
CSQUINP This specifies the sequential data set containing the definitions of the data structures to be
converted.
CSQUOUT This specifies the sequential data set where the conversion code fragments are to be written.
The logical record length (LRECL) must be 80 and the record format (RECFM) must be FB.