Como o CICS acessa o DB2
O CICS não acessa o DB2 diretamente — ele usa um componente intermediário chamado CICS DB2 Attachment Facility. Quando o CICS sobe, ele estabelece um pool de threads DB2. Cada tarefa CICS que executa SQL recebe uma thread desse pool e a devolve ao terminar (ou ao fazer SYNCPOINT).
| Componente | Papel |
|---|---|
| CICS DB2 Attachment Facility | Gerencia o pool de threads entre CICS e DB2 |
| Thread DB2 | Conexão lógica entre uma tarefa CICS e o subsistema DB2 |
| DSNCRCT (Resource Control Table) | Tabela que define parâmetros do pool: THRDM (máximo de threads), THRDNM (threads normais), TWAIT |
| Plan / Package | O plano de acesso (BIND) determina como o SQL será executado — um por transação CICS ou um por programa |
Configuração básica na DSNCRCT
* entrada na DSNCRCT para a transação CNTA
CNTA DSNCRCT TYPE=ENTRY,
PLAN=PGMCONTA, * plano DB2 associado à transação
THRDM=20, * máximo de threads simultâneas
THRDNM=10, * threads "normais" (pool pré-alocado)
TWAIT=YES * aguarda thread disponível se pool cheio
Unidade de trabalho — UOW
Uma UOW (Unit of Work) é o conjunto de alterações de banco de dados que devem ser confirmadas ou desfeitas juntas. No CICS, a UOW começa quando a tarefa faz o primeiro acesso ao DB2 e termina quando ocorre um SYNCPOINT (commit) ou SYNCPOINT ROLLBACK (rollback).
No modelo pseudo-conversacional, cada ciclo de entrada do usuário é uma tarefa CICS separada — portanto, uma UOW separada. Isso significa que:
| Situação | O que acontece com a UOW |
|---|---|
| Programa executa EXEC CICS RETURN | CICS faz SYNCPOINT automático — UOW é confirmada |
| Programa executa EXEC CICS XCTL | UOW continua — não há SYNCPOINT implícito no XCTL |
| Programa executa EXEC CICS LINK | UOW continua — SYNCPOINT pode ser feito no programa linkado |
| Ocorre abend CICS | CICS faz SYNCPOINT ROLLBACK automático — UOW é desfeita |
| Timeout de transação | CICS cancela a tarefa e faz ROLLBACK automático |
EXEC CICS SYNCPOINT — commit explícito
EXEC CICS SYNCPOINT confirma todas as alterações da UOW atual e inicia uma nova UOW. É o equivalente ao COMMIT WORK do DB2 standalone, mas coordenado pelo CICS com todos os gerenciadores de recursos (DB2, VSAM, TD).
PROCEDURE DIVISION.
CONFIRMAR-TRANSFERENCIA.
* debita conta origem
EXEC SQL
UPDATE CONTA
SET SALDO = SALDO - :WS-VALOR
WHERE NR_CONTA = :WS-CONTA-ORIGEM
END-EXEC
PERFORM CHECAR-SQLCODE
* credita conta destino
EXEC SQL
UPDATE CONTA
SET SALDO = SALDO + :WS-VALOR
WHERE NR_CONTA = :WS-CONTA-DESTINO
END-EXEC
PERFORM CHECAR-SQLCODE
* confirma as duas atualizações atomicamente
EXEC CICS SYNCPOINT
RESP(WS-RESP)
END-EXEC
IF WS-RESP = DFHRESP(NORMAL)
MOVE 'TRANSFERENCIA CONFIRMADA' TO MENSAGEMO
ELSE
MOVE 'ERRO AO CONFIRMAR - CONTATE SUPORTE'
TO MENSAGEMO
END-IF.
O SYNCPOINT coordena todos os recursos ao mesmo tempo:
| Recurso | O que acontece no SYNCPOINT |
|---|---|
| DB2 | COMMIT no subsistema DB2 — locks liberados, log gravado |
| VSAM via CICS | Alterações em arquivos VSAM confirmadas |
| Transient Data intrapartição | Registros gravados em TD se tornam visíveis para leitura |
| Temporary Storage | Não é afetado pelo SYNCPOINT — TS não participa da UOW |
SYNCPOINT ROLLBACK — desfazendo tudo
EXEC CICS SYNCPOINT ROLLBACK desfaz todas as alterações da UOW atual — DB2, VSAM, TD intrapartição — e inicia uma nova UOW limpa. É o equivalente ao ROLLBACK do SQL.
CHECAR-SQLCODE.
EVALUATE SQLCODE
WHEN 0
CONTINUE
WHEN OTHER
MOVE SQLCODE TO WS-SQLCODE-DISPLAY
MOVE 'ERRO DB2 - DESFAZENDO OPERACAO'
TO MENSAGEMO
* desfaz tudo que foi feito na UOW atual
EXEC CICS SYNCPOINT ROLLBACK
RESP(WS-RESP)
END-EXEC
EXEC CICS SEND MAP('MAPTRANS')
MAPSET('BANCMAP1')
FROM(MAPTRANSO)
END-EXEC
EXEC CICS RETURN
TRANSID(EIBTRNID)
COMMAREA(WS-COMMAREA)
END-EXEC
END-EVALUATE.
Two-phase commit — o protocolo por trás
Quando um SYNCPOINT é emitido, o CICS coordena o commit com todos os gerenciadores de recursos usando o protocolo two-phase commit (2PC). Isso garante que ou todos confirmam ou todos desfazem — nunca um meio-termo.
Fase 1 — Prepare
O CICS pergunta a cada gerenciador de recursos: "Você consegue confirmar?" O DB2 grava as alterações em seu log e responde "sim" (vote commit) ou "não" (vote abort). Se algum responder "não", o CICS cancela tudo.
Fase 2 — Commit ou Rollback
Se todos votaram "sim", o CICS envia a ordem de commit. Se algum votou "não" ou falhou, envia a ordem de rollback para todos os que já haviam votado "sim".
CICS DB2 VSAM
| | |
|--- PREPARE -------->| |
|--- PREPARE ---------|--------------------->|
|<-- VOTE COMMIT -----| |
|<-- VOTE COMMIT -----|----------------------|
|--- COMMIT --------->| |
|--- COMMIT -----------|-------------------->|
|<-- ACK --------------| |
|<-- ACK --------------|---------------------|
| | |
| UOW confirmada em todos os recursos
EXEC SQL COMMIT no CICS — por que evitar
Tecnicamente, é possível usar EXEC SQL COMMIT em um programa CICS. Porém, isso confirma apenas o DB2 — o CICS não é notificado e os demais recursos (VSAM, TD) ficam fora de sincronia. Isso quebra o protocolo 2PC e pode causar inconsistências.
| EXEC CICS SYNCPOINT | EXEC SQL COMMIT | |
|---|---|---|
| Coordena DB2 | Sim | Sim |
| Coordena VSAM | Sim | Não |
| Coordena TD | Sim | Não |
| Notifica o CICS | Sim | Não |
| Libera thread DB2 | Sim (com RELEASE) | Não |
| Uso recomendado | Sempre em CICS | Nunca em CICS |
EXEC CICS SYNCPOINT para commit e EXEC CICS SYNCPOINT ROLLBACK para rollback. Nunca use EXEC SQL COMMIT nem EXEC SQL ROLLBACK. A única exceção são programas que usam RMI (Resource Manager Interface) com configuração explícita — mas isso é raro e requer análise cuidadosa da arquitetura.
Programas threadsafe e o TCB do CICS
Por padrão, o CICS executa cada tarefa em um único TCB (Task Control Block) do z/OS, chamado QR TCB (Quasi-Reentrant TCB). Para acessar o DB2, a tarefa precisa alternar para um TCB aberto (open TCB ou T8 TCB) — essa alternância é custosa em termos de CPU.
Programas declarados como THREADSAFE no CSD podem rodar diretamente no TCB aberto, eliminando a alternância e reduzindo overhead de CPU significativamente em transações de alto volume.
* definição de programa threadsafe no CSD
DEFINE PROGRAM(PGMCONTA)
GROUP(BANCGRP)
LANGUAGE(COBOL)
EXECKEY(USER)
CONCURRENCY(THREADSAFE) * permite execução em TCB aberto
| CONCURRENCY | Comportamento | Overhead de TCB switch |
|---|---|---|
| QUASIRENT (padrão) | Sempre no QR TCB; muda para open TCB só para DB2, depois volta | Alto — 2 switches por acesso ao DB2 |
| THREADSAFE | Roda no open TCB; não precisa de switch para o DB2 | Nenhum |
| REQUIRED | Como THREADSAFE, mas o CICS garante que sempre usará TCB aberto | Nenhum |
RMI — Resource Manager Interface
O RMI (Resource Manager Interface) é o mecanismo pelo qual o CICS registra gerenciadores de recursos externos (como o DB2) para participar do protocolo 2PC. Quando o programa CICS usa EXEC SQL pela primeira vez em uma UOW, o DB2 Attachment Facility registra o DB2 como participante da UOW via RMI — automaticamente, sem ação do programador.
O programador precisa conhecer o RMI apenas em cenários avançados, como:
| Cenário | Relevância do RMI |
|---|---|
| Programa usa DB2 + MQ (IBM MQ) | Ambos precisam estar registrados via RMI para participar do 2PC |
| Programa usa múltiplos subsistemas DB2 | Cada subsistema é um participante RMI separado |
| Diagnóstico de UOW in-doubt | CICS mostra quais recursos RMI participaram da UOW no log de recovery |
Abend e recovery automático
Quando uma tarefa CICS sofre abend (erro irrecuperável), o CICS executa automaticamente uma sequência de cleanup:
1. CICS cancela a tarefa
2. CICS emite SYNCPOINT ROLLBACK implícito
→ DB2 desfaz todas as alterações da UOW
→ VSAM desfaz todas as alterações não confirmadas
→ TD intrapartição: registros não confirmados descartados
3. Thread DB2 é devolvida ao pool
4. CICS escreve mensagem no log (CSML / CSSL)
5. Terminal recebe mensagem de abend (ex: ASRA, AICA)
O programador pode interceptar o abend antes que o CICS faça o cleanup, usando HANDLE ABEND (visto no próximo artigo). Mas mesmo com HANDLE ABEND, se o programa emite EXEC CICS RETURN sem fazer SYNCPOINT, o CICS ainda vai confirmar automaticamente ao retornar.
Verificando o estado da UOW após erro
CHECAR-E-RECUPERAR.
EVALUATE SQLCODE
WHEN 0
CONTINUE
WHEN -911 * deadlock ou timeout
MOVE 'RECURSO OCUPADO, TENTE NOVAMENTE'
TO MENSAGEMO
EXEC CICS SYNCPOINT ROLLBACK END-EXEC
PERFORM EXIBIR-MENSAGEM-E-RETORNAR
WHEN -913 * deadlock confirmado
MOVE 'CONFLITO DE ACESSO - AGUARDE'
TO MENSAGEMO
EXEC CICS SYNCPOINT ROLLBACK END-EXEC
PERFORM EXIBIR-MENSAGEM-E-RETORNAR
WHEN OTHER
MOVE SQLCODE TO WS-SQLCODE-DISPLAY
STRING 'ERRO DB2: ' WS-SQLCODE-DISPLAY
DELIMITED SIZE INTO MENSAGEMO
EXEC CICS SYNCPOINT ROLLBACK END-EXEC
PERFORM EXIBIR-MENSAGEM-E-RETORNAR
END-EVALUATE.
Padrões de commit em transações online
Padrão 1 — commit implícito no RETURN (mais comum)
O padrão mais simples: toda a lógica de negócio cabe em um único ciclo pseudo-conversacional. O RETURN ao final confirma automaticamente.
PROCESSAR-SAQUE.
* 1. valida saldo
EXEC SQL SELECT SALDO INTO :WS-SALDO
FROM CONTA WHERE NR_CONTA = :WS-CONTA
END-EXEC
IF WS-SALDO < WS-VALOR-SAQUE
MOVE 'SALDO INSUFICIENTE' TO MENSAGEMO
PERFORM ENVIAR-TELA
STOP RUN * ← NUNCA no CICS; use EXEC CICS RETURN
END-IF
* 2. debita
EXEC SQL UPDATE CONTA
SET SALDO = SALDO - :WS-VALOR-SAQUE
WHERE NR_CONTA = :WS-CONTA
END-EXEC
PERFORM CHECAR-SQLCODE
* 3. exibe confirmação
MOVE 'SAQUE EFETUADO COM SUCESSO' TO MENSAGEMO
PERFORM ENVIAR-TELA
* 4. RETURN — CICS faz SYNCPOINT implícito aqui
EXEC CICS RETURN
TRANSID(EIBTRNID)
COMMAREA(WS-COMMAREA)
END-EXEC.
Padrão 2 — tela de confirmação com SYNCPOINT explícito
Para operações críticas (transferências, pagamentos), o usuário vê os dados e confirma antes de qualquer UPDATE. O SYNCPOINT explícito acontece apenas quando o usuário pressiona ENTER na tela de confirmação.
* ciclo 1: usuário informa dados, programa exibe resumo
FASE-REVISAO.
PERFORM RECEIVE-DADOS-ENTRADA
PERFORM VALIDAR-DADOS
MOVE 'C' TO WS-FASE * próxima fase = confirmar
PERFORM EXIBIR-TELA-CONFIRMACAO
EXEC CICS RETURN * sem UPDATE ainda — apenas leitura
TRANSID(EIBTRNID)
COMMAREA(WS-COMMAREA)
END-EXEC.
* ciclo 2: usuário pressionou ENTER confirmando
FASE-CONFIRMAR.
PERFORM EXECUTAR-UPDATES-DB2
EXEC CICS SYNCPOINT * confirma explicitamente
RESP(WS-RESP)
END-EXEC
IF WS-RESP = DFHRESP(NORMAL)
MOVE 'OPERACAO CONFIRMADA' TO MENSAGEMO
ELSE
MOVE 'FALHA NA CONFIRMACAO' TO MENSAGEMO
END-IF
PERFORM EXIBIR-MENSAGEM
EXEC CICS RETURN
TRANSID(EIBTRNID)
COMMAREA(WS-COMMAREA)
END-EXEC.
Padrão 3 — múltiplos SYNCPOINTs em transações longas
Transações que processam muitos registros (relatórios online, transferências em lote iniciadas pelo usuário) podem fazer SYNCPOINT intermediário para liberar locks e evitar timeout de UOW.
PROCESSAR-LOTE.
MOVE 0 TO WS-CONTADOR
PERFORM UNTIL FIM-DA-LISTA
PERFORM LER-PROXIMO-ITEM
IF NAO-FIM
PERFORM PROCESSAR-ITEM
ADD 1 TO WS-CONTADOR
* SYNCPOINT a cada 50 registros
IF WS-CONTADOR = 50
EXEC CICS SYNCPOINT RESP(WS-RESP) END-EXEC
IF WS-RESP NOT = DFHRESP(NORMAL)
PERFORM TRATAR-ERRO-SYNCPOINT
END-IF
MOVE 0 TO WS-CONTADOR
END-IF
END-IF
END-PERFORM
* SYNCPOINT final para os itens restantes
EXEC CICS SYNCPOINT RESP(WS-RESP) END-EXEC.
RELEASE=YES for especificado na configuração do attachment facility. Isso aumenta a disponibilidade de threads para outras tarefas no pool. O próximo acesso ao DB2 adquire uma nova thread automaticamente.