1. COBOL batch consumindo fila MQ

Um programa COBOL batch que drena uma fila de pedidos e processa cada mensagem:

WORKING-STORAGE SECTION. 01 WS-HCONN PIC S9(9) COMP. 01 WS-HOBJ PIC S9(9) COMP. 01 WS-COMPCODE PIC S9(9) COMP. 01 WS-REASON PIC S9(9) COMP. 01 WS-MSG-BUFFER PIC X(4096). 01 WS-MSG-LEN PIC S9(9) COMP. 01 WS-MAX-LEN PIC S9(9) COMP VALUE 4096. COPY CMQV. Constantes MQ COPY CMQMD. Estrutura MQMD COPY CMQPMO. Estrutura MQPMO COPY CMQGMO. Estrutura MQGMO COPY CMQOD. Estrutura MQOD PROCEDURE DIVISION. CALL 'MQCONN' USING 'CSQ1' WS-HCONN WS-COMPCODE WS-REASON PERFORM CHECK-CC MOVE 'FILA.PEDIDOS' TO MQOD-OBJNAME CALL 'MQOPEN' USING WS-HCONN MQOD MQOO-INPUT-EXCLUSIVE WS-HOBJ WS-COMPCODE WS-REASON PERFORM CHECK-CC MOVE MQGMO-SYNCPOINT TO MQGMO-OPTIONS MOVE MQWI-UNLIMITED TO MQGMO-WAITINTERVAL PERFORM UNTIL WS-REASON = MQRC-NO-MSG-AVAILABLE CALL 'MQGET' USING WS-HCONN WS-HOBJ MQMD MQGMO WS-MAX-LEN WS-MSG-BUFFER WS-MSG-LEN WS-COMPCODE WS-REASON EVALUATE TRUE WHEN WS-REASON = MQRC-NONE PERFORM PROCESSAR-PEDIDO CALL 'MQCMIT' USING WS-HCONN WS-COMPCODE WS-REASON WHEN WS-REASON = MQRC-NO-MSG-AVAILABLE CONTINUE WHEN OTHER CALL 'MQBACK' USING WS-HCONN WS-COMPCODE WS-REASON PERFORM TRATAR-ERRO END-EVALUATE END-PERFORM CALL 'MQCLOSE' USING WS-HCONN WS-HOBJ MQCO-NONE WS-COMPCODE WS-REASON CALL 'MQDISC' USING WS-HCONN WS-COMPCODE WS-REASON STOP RUN.

2. Trigger — processamento automático

Em vez de um programa ficar em loop esperando mensagens, o MQ pode disparar automaticamente um programa quando uma mensagem chega na fila — isso é o mecanismo de trigger.

/* Configurar trigger na fila */ ALTER QLOCAL(FILA.PEDIDOS) TRIGGER TRIGTYPE(FIRST) TRIGDPTH(1) TRIGMPRI(0) INITQ(SYSTEM.DEFAULT.INITIATION.QUEUE) PROCESS(PROC.PEDIDOS) /* Definir o processo que será disparado */ DEFINE PROCESS(PROC.PEDIDOS) APPLICID('BATCHPED') APPLTYPE(ZOS) DESCR('Processa pedidos recebidos')

Como funciona: quando a primeira mensagem chega em FILA.PEDIDOS (TRIGTYPE(FIRST)), o MQ grava um trigger message na INITIATION.QUEUE. O Trigger Monitor (programa CSQQTRMN no z/OS) lê essa trigger message e inicia o programa BATCHPED. O programa processa as mensagens e termina. Na próxima mensagem, o ciclo se repete.

3. MQ em transações CICS

O CICS tem integração nativa com o MQ via CICS-MQ Bridge e via chamadas diretas à API MQ dentro de transações CICS:

* Transação CICS que envia mensagem ao MQ WORKING-STORAGE SECTION. COPY CMQV. COPY CMQMD. COPY CMQPMO. COPY CMQOD. 01 WS-HCONN PIC S9(9) COMP. 01 WS-HOBJ PIC S9(9) COMP. 01 WS-CC PIC S9(9) COMP. 01 WS-RC PIC S9(9) COMP. PROCEDURE DIVISION. * Em CICS, usar MQCONN com nome do QM vazio * para conectar ao QM padrão do CICS CALL 'MQCONN' USING SPACES WS-HCONN WS-CC WS-RC MOVE 'FILA.NOTIF' TO MQOD-OBJNAME CALL 'MQOPEN' USING WS-HCONN MQOD MQOO-OUTPUT WS-HOBJ WS-CC WS-RC MOVE MQPER-PERSISTENT TO MQMD-PERSIST MOVE MQPMO-SYNCPOINT TO MQPMO-OPTIONS MOVE WS-PAYLOAD TO WS-MSG-BUFFER CALL 'MQPUT' USING WS-HCONN WS-HOBJ MQMD MQPMO WS-MSG-LEN WS-MSG-BUFFER WS-CC WS-RC CALL 'MQCLOSE' USING WS-HCONN WS-HOBJ MQCO-NONE WS-CC WS-RC CALL 'MQDISC' USING WS-HCONN WS-CC WS-RC * EXEC CICS SYNCPOINT faz o commit — inclui o MQPUT EXEC CICS SYNCPOINT END-EXEC EXEC CICS RETURN END-EXEC.

💡 Sincronismo entre CICS e MQ

Quando MQPMO-SYNCPOINT é usado em CICS, o PUT MQ faz parte da unidade de trabalho CICS. Se o programa fizer EXEC CICS SYNCPOINT, a mensagem é confirmada; se fizer EXEC CICS SYNCPOINT ROLLBACK ou der ABEND, o MQ automaticamente desfaz o PUT. Isso garante consistência entre o banco de dados CICS e as mensagens MQ.

4. Padrão request-reply

O padrão request-reply permite comunicação pseudo-síncrona via MQ — muito usado entre o mainframe e sistemas externos:

Aplicação A (requester) — mainframe: 1. Criar fila temporária de resposta (QMODEL) MQOPEN(MODELO.RESPOSTA, MQOO-OUTPUT+MQOO-INPUT-EXCLUSIVE) → MQ cria FILA.RESP.AMQ.xxxxxxxx automaticamente 2. Montar MQMD com: MQMD-MSGTYPE = MQMT-REQUEST MQMD-REPLYTOQ = 'FILA.RESP.AMQ.xxxxxxxx' MQMD-REPLYTOQM = 'CSQ1' 3. MQPUT na fila de pedidos do sistema B 4. MQGET na fila temporária aguardando resposta MQGMO-WAITINTERVAL = 30000 (timeout 30 segundos) Aplicação B (replier) — sistema externo: 1. MQGET da mensagem de pedido 2. Processar o pedido 3. MQPUT na REPLYTOQ com: MQMD-MSGTYPE = MQMT-REPLY MQMD-CORRELID = MsgId da mensagem de pedido

5. Dead Letter Queue — tratamento de erros

Quando o MQ não consegue entregar uma mensagem (fila cheia, tipo incorreto, QM indisponível), a mensagem é movida para a Dead Letter Queue (DLQ) com um cabeçalho MQDLH que explica o motivo:

/* Configurar DLQ no Queue Manager */ ALTER QMGR DEADQ(SISTEMA.DLQ) Estrutura MQDLH (Dead Letter Header): StrucId = 'DLH ' Reason = código do erro (ex: 2192 = MQRC_Q_FULL) DestQName = nome da fila destino original DestQMgrName = Queue Manager destino original PutDate / PutTime = quando foi movida para a DLQ /* Ver mensagens na DLQ */ DISPLAY QSTATUS(SISTEMA.DLQ) CURDEPTH /* DLQ Handler — programa AMQSDLQ lê e processa DLQ */ /* Regras típicas de um DLQ Handler: */ INPUT(SISTEMA.DLQ) ACTION(RETRY) REASON(2162) RETRIES(3) RETRYINT(60) /* Se MQRC_Q_FULL: tentar 3 vezes a cada 60 segundos */ ACTION(FWD) REASON(2085) FWDQ(DLQ.ERRO.DESTINO) /* Se fila não existe: encaminhar para fila de erro */ ACTION(DISCARD) REASON(*) HEADER(YES) /* Qualquer outro: descartar (gravar no log) */