MQ/204 programming: Difference between revisions

From m204wiki
Jump to navigation Jump to search
(Created page with "This topic provides programming tips for MQ/204, including a sample application and a list of unsupported features. ==Programm...")
 
No edit summary
Line 1: Line 1:
This topic provides programming tips for MQ/204, including a [[#Sample application|sample application]] and a list of [[#MQ/204 restrictions|unsupported features]].
This topic provides programming tips for MQ/204, including a [[#MQ/204 sample application|sample application]] and a list of [[#MQ/204 restrictions|unsupported features]].
==Programming suggestions==
==Programming suggestions==



Revision as of 19:47, 11 November 2015

This topic provides programming tips for MQ/204, including a sample application and a list of unsupported features.

Programming suggestions

Removing messages that cause errors

Occasionally a message taken from a queue causes an error; that is, the error is in the message. When you back out and try to retrieve the message again, the error recurs.

To break this back out loop, set the MARK_SKIP_BACKOUT option in a subsequent MQGET statement. When this option is set, the message taken from the queue under syncpoint control is not placed back on the queue when a user or the Online issues an MQBACK statement.

Removing messages that do not convert

By default WebSphere MQ tries to perform a data conversion, for example from EBCDIC to ASCII. If you issue an MQGET statement for a message that fails to convert, the message becomes stuck on the queue.

To get the message off the queue, reissue the MQGET statement with the NO_CONVERT option. The message can now be taken off the queue, because the MQGET processing completes successfully, as in the following example:

MQGET IF $STATUS=12 $STATUSD=8 THEN MQGET... NO_CONVERT %CONVERTED_FLAG=0

Saving a permanent local dynamic queue name

If your application creates permanent local dynamic queues that make use of queue name patterns, you might want to save the name of the generated permanent local dynamic queue in case the run comes down unexpectedly.

To save a permanent local dynamic queue name:

  1. Issue an OPEN QUEUE statement with the MODEL and DYNAMICQNAME options that specifies the permanent local dynamic queue that you want to save.
  2. Use the $MQ_QUEUENAME function to obtain the full external name of the queue.
  3. Store the full external queue name in a procedure that your run includes when it comes up. Or, you can store it in a database so a procedure that your run includes when it comes up can dynamically generate the DEFINE QUEUE command to identify the queue.

When you decide to delete the queue, remove the queue name from the procedure or database.

Working with logically deleted queues

On z/OS, until the last message and request are closed, the queue is logically deleted but still exists. For example, you can still display the queue. However, you cannot retrieve messages or put messages on a logically deleted queue. During this state, any attempt to create a new queue, either local dynamic or predefined, with the same name fails. In the case of a local dynamic queue, the OPEN QUEUE statement fails with the reason code QRC_NAME_IN_USE. This is true for the application that logically deleted the queue, as well as for other applications.

After the last reference to the queue is closed, the queue is physically deleted; you can now create a new queue with the same name. However, in the case of a temporary local dynamic queue, if any corresponding unresolved units of work are outstanding, the queue can be physically deleted only when the application, which is holding the queue open, terminates.

Occasionally a logically deleted, permanent local dynamic queue has uncommitted updates. In this case, the queue is physically deleted only after resolving the corresponding units of work, as well as closing all the handles.

Tuning MQ/204

Consider the following ways to improve the performance of MQ/204:

  • Set the initial value of UBUFSZ accurately.
  • Make sure that the number of MQ/204 subtasks is optimal. When this setting is too low, the elapsed time for individual users might be higher than necessary, because they must wait for a free subtask. Too many subtasks may cause additional z/OS expenses to control subtasks.
  • WebSphere MQ performance can be affected by message size. WebSphere MQ performance tends to be relatively better when large message sizes, above 4K, are used.
  • Tune WebSphere MQ according to the recommendations of WebSphere MQ system managers and documentation.

Greenwich Mean Time and MQPUT, MQPUT1, and MQGET time

WebSphere MQ uses Greenwich Mean Time (GMT) when storing messages, because it is a transport tool that can pass messages across multiple time zones. WebSphere MQ does not have a parameter that you can set to use local time rather than Greenwich Mean Time.

If your site has chosen to reset the clock on your mainframe from Greenwich Mean Time to your local time, rather than keeping the mainframe on Greenwich Mean Time and calculating the local time offset, you might notice that the time-stamp for MQPUT statements is offset from the time-stamps of WebSphere MQ on PCs and other mainframes in your network.

See Applying date and time-stamps to messages for a more detailed discussion.

Increase in STBL for MQ/204 sites

In Model 204 V6R3.0 and later, the increased STBL requirement is because MQ control blocks are kept in STBL, and they have increased in size by several hundred bytes. The increase depends on how many MQPUT and MQGET statements are compiled in any one transaction, so it will be the high water mark for the largest SOUL compilations.

MQ/204 sample application

The following annotated application sends and retrieves two messages.

Although omitted from the application to save space, do the following:

  • Issue a SETGRC command to check that the DEFINE commands and START command work.
  • Check $STATUS and $STATUSD after opening and closing the queues.

B %X=$SETG('TIMES',2) END * The following commands define a queue manager, then a queue, * and launch the queue manager. You must define a queue manager * before you define a queue, because a queue cannot exist (or be * defined) without a queue manager. DEFINE QM CCAQM1 WITH SCOPE=SYSTEM QMNAME=CSQ1 DEFINE Q CCAQM1Q1 WITH SCOPE=SYSTEM QM=CCAQM1 - QNAME=DVCCA.TEST2.PS.Q01 START QM CCAQM1 * BEGIN VARIABLES ARE UNDEFINED %MSGID IS STRING LEN 24 %MSGID=$SUBSTR($USER,1,8) WITH $SUBSTR($DATE(2,''),2) WITH - $SUBSTR($TIME,1,2) WITH - $SUBSTR($TIME,4,2) WITH - $SUBSTR($TIME,7,2) PRINT 'MESSAGE ID ="' %MSGID '"' %X IS STRING LEN 4 %X=$SETG('MSGID',%MSGID) %TEXT IS STRING LEN 255 %INDEX IS FLOAT * Within the SUBROUTINE...END SUBROUTINE statement, the * PRINT.STATUS subroutine checks whether $STATUS or $STATUSD is * other than zero; if so, it prints the values. PRINT.STATUS * subroutine is called several times during this application to * provide queue information. SUBROUTINE PRINT.STATUS IF $STATUS NE 0 OR $STATUSD NE 0 THEN PRINT '$STATUS/$STATUSD=' WITH $STATUS WITH '/' WITH $STATUSD SKIP 1 LINE END IF RETURN END SUBROUTINE * The following code opens a queue (CCAQM1Q1) and calls the * PRINT.STATUS subroutine. The FOR loop creates a message and * puts it on the queue (MQPUT statement). OPEN QUEUE CCAQM1Q1 OUTPUT CALL PRINT.STATUS PRINT 'ADDING ?&TIMES MESSAGES' FOR %INDEX FROM 1 TO ?&TIMES BY 1 *PRINT 'ABOUT TO ADD FOLLOWING MESSAGE TO THE QUEUE' %TEXT='!! THAT''S AMAZING AT ' WITH $TIME WITH ' !!' - WITH %INDEX WITH ' ' WITH %MSGID PRINT %TEXT MQPUT %TEXT ON CCAQM1Q1 MSGID=%MSGID CALL PRINT.STATUS END FOR CLOSE QUEUE CCAQM1Q1 CALL PRINT.STATUS END * BEGIN VARIABLES ARE UNDEFINED %TEXT IS STRING LEN 255 %MSGID IS STRING LEN 24 %MSGID=$GETG('MSGID') SUBROUTINE PRINT.STATUS IF $STATUS NE 0 OR $STATUSD NE 0 THEN PRINT '$STATUS/$STATUSD=' WITH $STATUS WITH '/' WITH $STATUSD SKIP 1 LINE END IF RETURN END SUBROUTINE OPEN QUEUE CCAQM1Q1 CALL PRINT.STATUS PRINT 'ATTEMPT TO RETRIEVE ?&TIMES MESSAGES' * The following REPEAT loop retrieves the messages. REPEAT ?&TIMES TIMES MQGET %TEXT FROM CCAQM1Q1 NO_WAIT MSGID=%MSGID CALL PRINT.STATUS PRINT $TIME WITH ' MQGET: ' WITH %TEXT END REPEAT CLOSE QUEUE CCAQM1Q1 CALL PRINT.STATUS END

Sample output

MESSAGE ID="00003980501121739" ADDING 2 MESSAGES !! THAT'S AMAZING AT 12:17:39 !!1 00003980501121739 !! THAT'S AMAZING AT 12:17:40 !!2 00003980501121739 ATTEMPT TO RETRIEVE 2 MESSAGES 12:17:40 MQGET: !! THAT'S AMAZING AT 12:17:39 !!1 00003980501121739 12:17:40 MQGET: !! THAT'S AMAZING AT 12:17:40 !!2 00003980501121739

MQ/204 restrictions

The WebSphere MQ API supports a set of features that permits many functions to be performed with queues. The MQ/204 interface supports many, but not all these features. The following features are not supported:

  • MQINQ and MQSET, query and set attributes of objects.
  • Direct access to the MQCONN and MQDISC calls or connection handles.

    Connections to queue managers are handled internally by OPEN QUEUE and CLOSE QUEUE statements. (See the WebSphere MQ documentation for a discussion of connection handles.)

  • Direct access to the WebSphere MQ control blocks (get message options, put message options, and so on), except for the message descriptors on MQGET statements.

    MQ/204 is a higher level keyword based interface, which limits functions to those within the keyword interface.

  • WebSphere MQ API method of asynchronously fetching messages (the WebSphere MQ option MQGMO_SET_SIGNAL).