IBM MQ · Avançado
MQ com COBOL e CICS
20 min de leitura
Nível: Intermediário
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) */