Mainframe Path Start learning free
Core12 min readLesson 3 of 4

Programming with the MQI in COBOL

Programs talk to MQ through a small set of calls known as the MQI. A COBOL program connects, opens a queue, puts or gets messages, closes and disconnects, checking a completion code and reason code after every call.

The core calls

CallPurpose
MQCONNConnect to a queue manager and get a connection handle (not needed in CICS, which connects for you)
MQOPENOpen a queue for input, output or inquiry, returning an object handle
MQPUTPut a message on an open queue
MQGETGet a message, optionally waiting for one to arrive
MQPUT1Open, put one message and close, in a single call
MQCLOSERelease the object handle
MQDISCDisconnect from the queue manager
MQCMIT / MQBACKCommit or back out a unit of work in batch (in CICS, use CICS SYNCPOINT instead)

A put in COBOL

COBOL: put a payment message
    MOVE MQOT-Q          TO MQOD-OBJECTTYPE
    MOVE 'PAYMENTS.IN'   TO MQOD-OBJECTNAME
    COMPUTE OPEN-OPTIONS = MQOO-OUTPUT + MQOO-FAIL-IF-QUIESCING
    CALL 'MQOPEN' USING HCONN MQOD OPEN-OPTIONS
                        HOBJ COMPCODE REASON
    IF COMPCODE NOT = MQCC-OK
       PERFORM MQ-ERROR
    END-IF

    MOVE MQPER-PERSISTENT TO MQMD-PERSISTENCE
    COMPUTE MQPMO-OPTIONS = MQPMO-SYNCPOINT
                          + MQPMO-NEW-MSG-ID
    CALL 'MQPUT' USING HCONN HOBJ MQMD MQPMO
                       BUFFER-LENGTH PAYMENT-REC
                       COMPCODE REASON

The structures (MQOD for object descriptor, MQMD, MQPMO for put options, MQGMO for get options) and the constants come from IBM-supplied copybooks such as CMQV, CMQODV, CMQMDV, CMQPMOV and CMQGMOV. Copy them in rather than coding values by hand.

Completion and reason codes

Every call returns a completion code (MQCC-OK 0, MQCC-WARNING 1, MQCC-FAILED 2) and a reason code that says why. These are the ones you will meet most:

ReasonNameUsual meaning
2033MQRC_NO_MSG_AVAILABLEThe queue is empty (normal at the end of a get loop)
2085MQRC_UNKNOWN_OBJECT_NAMEThe queue name is wrong or not defined on this queue manager
2035MQRC_NOT_AUTHORIZEDThe user ID lacks access in RACF to the queue or queue manager
2053MQRC_Q_FULLThe queue reached MAXDEPTH; the reader is probably down
2059MQRC_Q_MGR_NOT_AVAILABLEThe queue manager is not running or not reachable
2009MQRC_CONNECTION_BROKENThe connection was lost during the call
2080MQRC_TRUNCATED_MSG_FAILEDThe buffer is smaller than the message

Getting with a wait

A reader usually sets MQGMO-WAIT with a wait interval so it sleeps until a message arrives instead of looping. When the interval expires with nothing on the queue, the get returns reason 2033 and the program can end cleanly or wait again.

Request and reply

For a request/reply exchange the requester sets ReplyToQ in the MQMD. The server copies the request's MsgId into the reply's CorrelId, and the requester gets the reply by correlation ID. This is how a CICS program matches each answer to its question.

TRY IT YOURSELF

A get loop ends with completion code 2 and reason code 2033. Is this an error the program should report, or the normal 'queue is empty' signal? Answer error or normal.

Show a hint

Look up 2033 in the table above.

Show the solution

normal: 2033 (MQRC_NO_MSG_AVAILABLE) means there was nothing to get. Well-written programs treat it as the end of the loop, not as a failure.

Common mistakes

Using MQCMIT inside CICS

In CICS the unit of work belongs to CICS. Commit with EXEC CICS SYNCPOINT so MQ and DB2 updates commit together.

Treating every non-zero reason code as fatal

2033 at the end of a get loop is expected. Check the specific reason code, not just the completion code.

Getting outside syncpoint for important messages

Without MQGMO-SYNCPOINT the message is gone the moment you get it. If the program then abends, the message is lost.

What you will see at work

Key terms

Check your understanding.
Take this lesson's quiz and save your progress. Free.

Take the lesson quiz
← Queue managers, queues and channelsRunning and troubleshooting MQ →