1. Batch vs. online — o mundo CICS

A diferença fundamental entre um programa batch e um programa CICS está em quem dispara a execução e quanto tempo ela dura:

Comparação Batch vs. CICS online
  Característica     Batch (JCL)               CICS Online
  ─────────────────  ────────────────────────  ────────────────────────────
  Iniciado por       Scheduler / operador       Usuário digitando TRANSID
  Duração            Minutos a horas            Milissegundos a segundos
  Interação          Nenhuma (arquivo entrada)  Tela → programa → tela
  Múltiplos usuários Um job por vez             Milhares simultâneos
  Acesso a arquivos  OPEN/READ/CLOSE direto     Via comandos EXEC CICS
  Acesso a DB2       EXEC SQL direto            EXEC SQL (mesma sintaxe)
  Termina com        STOP RUN                   EXEC CICS RETURN
  Memória            Working-Storage persiste   Working-Storage reinicia
                     durante o job              a cada transação!

⚠️ Working-Storage não persiste entre telas no CICS

No batch, a Working-Storage existe durante toda a execução do job. No CICS pseudo-conversacional, o programa termina ao enviar cada tela e é recarregado do zero quando o usuário pressiona Enter. Isso significa que todos os campos da Working-Storage voltam ao valor inicial declarado. O dado que precisa sobreviver entre uma tela e a próxima deve ser passado via COMMAREA.

Conceitos-chave do CICS

Glossário Termos essenciais
  TRANSID    Código de 4 caracteres que identifica uma transação
             (ex: CONS, TRAN, EXTX) — o usuário digita isso na tela
  TASK       Uma execução de uma transação para um usuário
  TERMINAL   O terminal 3270 do usuário (ID único, ex: TRM1)
  MAPSET     PDS member com definições de telas BMS compiladas
  MAP        Uma tela individual dentro de um MAPSET
  COMMAREA   Área de comunicação passada entre ciclos ou programas
  EIB        Execute Interface Block — informações da tarefa atual
  EIBRESP    Código de resposta do último EXEC CICS
  EIBCALEN   Comprimento da COMMAREA recebida (0 = primeira vez)

2. EXEC CICS — sintaxe básica

Assim como o SQL usa EXEC SQL … END-EXEC, os comandos CICS usam EXEC CICS … END-EXEC. O pré-compilador CICS (DFHECP1$) os transforma em CALLs antes da compilação COBOL.

COBOL Estrutura de um programa CICS mínimo
       IDENTIFICATION DIVISION.
           PROGRAM-ID. PGMCONS.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

             * Copia o EIB (Execute Interface Block) — sempre inclua
           COPY DFHEIBLK.
             * Copia definições de resposta CICS (DFHRESP)
           COPY DFHAID.    *teclas de atenção: DFHENTER, DFHPF1…PF24, DFHCLEAR

       01  WS-RESP       S9(08) COMP.
       01  WS-RESP2      S9(08) COMP.

       LINKAGE SECTION.
       01  DFHCOMMAREA   PIC X(100).  *COMMAREA recebida

       PROCEDURE DIVISION.

       0000-INICIO.
           IF EIBCALEN = 0
               PERFORM 1000-PRIMEIRA-VEZ
           ELSE
               PERFORM 2000-RETORNO-USUARIO
           END-IF.

       9999-FIM.
           EXEC CICS RETURN
               TRANSID('CONS')
               COMMAREA(WS-COMMAREA)
               LENGTH(100)
           END-EXEC.   *aguarda próximo Enter do usuário

✅ COPY DFHEIBLK e DFHAID são obrigatórios

DFHEIBLK gera a estrutura do EIB (Execute Interface Block) com campos como EIBCALEN, EIBTRNID, EIBTERMID, EIBAID e EIBRESP. DFHAID gera constantes para as teclas de atenção (DFHENTER, DFHPF3, DFHCLEAR etc.) que você compara com EIBAID para saber qual tecla o usuário pressionou.

3. Modelo pseudo-conversacional

No modelo conversacional, o programa fica esperando o usuário digitar — isso ocuparia uma task inteira e seus recursos durante segundos (uma eternidade para o mainframe). No modelo pseudo-conversacional, o programa envia a tela, devolve o controle ao CICS com EXEC CICS RETURN TRANSID(…), e só é recarregado quando o usuário pressiona uma tecla:

Diagrama Ciclo pseudo-conversacional
  Usuário digita CONS    ──►  CICS inicia PGMCONS
                                    │
                              EIBCALEN = 0? SIM
                                    │
                              Monta tela vazia
                              EXEC CICS SEND MAP
                              EXEC CICS RETURN TRANSID('CONS')
                                    │
  Programa termina        ◄──  CICS suspende task
  (Working-Storage liberada)
                                    │
  Usuário preenche e       ──►  CICS reinicia PGMCONS
  pressiona ENTER               (Working-Storage zerada!)
                                    │
                              EIBCALEN > 0? SIM — lê COMMAREA
                              EXEC CICS RECEIVE MAP — lê campos
                              Valida, processa, atualiza DB2
                              EXEC CICS SEND MAP (resultado)
                              EXEC CICS RETURN TRANSID('CONS')
                                    │
  Ciclo se repete         ◄──  CICS suspende task novamente

🦕 Analogia — o garçom que some entre pedidos

Imagine um restaurante onde o garçom anota o pedido, entrega na cozinha e desaparece. Quando o prato fica pronto, qualquer garçom disponível o leva à mesa. O cliente não percebe a diferença — parece que foi o mesmo garçom. No CICS, o "garçom" é a task COBOL: ela entrega a tela (pedido), termina, e é recriada quando o usuário responde. A COMMAREA é a anotação do pedido que o garçom novo recebe para saber o contexto.

4. COMMAREA — passando dados entre ciclos

A COMMAREA é uma área de memória que o CICS preserva entre os ciclos de uma mesma transação, e também entre programas chamados via LINK. No programa, ela é recebida na LINKAGE SECTION como DFHCOMMAREA.

COBOL COMMAREA — estrutura típica
       WORKING-STORAGE SECTION.

             * Estrutura que será passada como COMMAREA
       01  WS-COMMAREA.
           05  CA-TRANSACAO   PIC X(02).  *fase: '01'=entrada, '02'=confirma
           05  CA-NR-CONTA    PIC X(10).
           05  CA-VL-SALDO    S9(13)V99 COMP-3.
           05  CA-NOME        X(40).
           05  CA-MSG-ERRO    X(60).

       LINKAGE SECTION.
       01  DFHCOMMAREA.   *CICS preenche com a COMMAREA do ciclo anterior
           05  CA-TRANSACAO   PIC X(02).
           05  CA-NR-CONTA    PIC X(10).
           05  CA-VL-SALDO    S9(13)V99 COMP-3.
           05  CA-NOME        X(40).
           05  CA-MSG-ERRO    X(60).

       PROCEDURE DIVISION.

       0000-INICIO.
           IF EIBCALEN = 0
                     * Primeira execução — inicializa WS-COMMAREA
               INITIALIZE WS-COMMAREA
               MOVE '01' TO CA-TRANSACAO OF WS-COMMAREA
           ELSE
                     * Retorno do usuário — copia DFHCOMMAREA para WS
               MOVE DFHCOMMAREA TO WS-COMMAREA
           END-IF

           EVALUATE CA-TRANSACAO OF WS-COMMAREA
               WHEN '01'  PERFORM 1000-TELA-ENTRADA
               WHEN '02'  PERFORM 2000-TELA-CONFIRMA
               WHEN OTHER PERFORM 9000-ERRO-FASE
           END-EVALUATE

           EXEC CICS RETURN
               TRANSID('CONS')
               COMMAREA(WS-COMMAREA)
               LENGTH(117)
           END-EXEC.

💗 EIBCALEN = 0 significa "primeira vez"

EIBCALEN (EIB Communication Area Length) contém o tamanho da COMMAREA recebida. Na primeira execução de uma transação, não há COMMAREA — logo EIBCALEN = 0. Em todas as execuções subsequentes (o usuário pressionou Enter), EIBCALEN > 0 e DFHCOMMAREA tem os dados do ciclo anterior. Checar EIBCALEN = 0 é a forma padrão de detectar a "primeira vez".

5. BMS — mapas de tela

O BMS (Basic Mapping Support) define as telas do terminal 3270. Um mapa BMS é um arquivo de macro assembler que descreve campos, posições, atributos (proteção, cor, intensidade) e é compilado gerando um mapset em PDS. O COBOL não desenha a tela diretamente — envia e recebe o mapa já compilado.

Assembler BMS Definição de mapa — MPCONS (consulta de conta)
  MSCONSUL DFHMSD TYPE=MAP,                                         X
                 LANG=COBOL,                                        X
                 MODE=INOUT,                                        X
                 STORAGE=AUTO,                                      X
                 TIOAPFX=YES

  MPCONSUL DFHMDI SIZE=(24,80),                                     X
                 LINE=1,COLUMN=1

           DFHMDF POS=(1,1),LENGTH=30,                             X
                 INITIAL='  CONSULTA DE CONTA CORRENTE',           X
                 ATTRB=(PROT,ASKIP)

           DFHMDF POS=(3,1),LENGTH=12,                             X
                 INITIAL='NR. CONTA  :',ATTRB=(PROT,ASKIP)
  CONTAO   DFHMDF POS=(3,14),LENGTH=10,ATTRB=(UNPROT,FSET)

           DFHMDF POS=(5,1),LENGTH=12,                             X
                 INITIAL='TITULAR    :',ATTRB=(PROT,ASKIP)
  NOMEO    DFHMDF POS=(5,14),LENGTH=40,ATTRB=(PROT,ASKIP)

           DFHMDF POS=(7,1),LENGTH=12,                             X
                 INITIAL='SALDO      :',ATTRB=(PROT,ASKIP)
  SALDOO   DFHMDF POS=(7,14),LENGTH=16,ATTRB=(PROT,ASKIP)

  MSGO     DFHMDF POS=(23,1),LENGTH=78,ATTRB=(PROT,ASKIP,BRT)

           DFHMSD TYPE=FINAL

O DCLGEN do mapa (gerado pela compilação BMS) cria uma estrutura COBOL que o programa usa:

COBOL Estrutura gerada pelo BMS (COPY MPCONSUL)
      * Estrutura de INPUT (sufixo I) — lida com RECEIVE MAP
       01  MPCONSULI.
           02  FILLER     PIC X(12).   *header do mapa
           02  CONTAL     S9(4) COMP. *comprimento do campo
           02  CONTAA     X(1).        *atributo
           02  CONTAI     X(10).       *valor digitado pelo usuário
                      … outros campos …

      * Estrutura de OUTPUT (sufixo O) — enviada com SEND MAP
       01  MPCONSULO.
           02  FILLER     X(12).
           02  CONTAL     S9(4) COMP.
           02  CONTAA     X(1).        *você pode mudar atributo em runtime
           02  CONTAO     X(10).       *valor a exibir
           02  NOMEO      X(40).
           02  SALDOO     X(16).
           02  MSGO       X(78).       *linha de mensagem

6. SEND MAP e RECEIVE MAP

COBOL SEND MAP — enviando tela ao terminal
       1000-ENVIA-TELA-ENTRADA.
           INITIALIZE MPCONSULO
           MOVE 'INFORME O NUMERO DA CONTA E PRESSIONE ENTER'
               TO MSGO

           EXEC CICS SEND MAP('MPCONSUL')
                         MAPSET('MSCONSUL')
                         FROM(MPCONSULO)
                         ERASE          *limpa a tela antes de enviar
                         CURSOR         *posiciona cursor no 1o campo UNPROT
                         RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP.

       2000-RECEBE-ENTRADA.
           INITIALIZE MPCONSULI

           EXEC CICS RECEIVE MAP('MPCONSUL')
                             MAPSET('MSCONSUL')
                             INTO(MPCONSULI)
                             RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP

                 * Verifica qual tecla o usuário pressionou
           EVALUATE EIBAID
               WHEN DFHENTER  PERFORM 3000-PROCESSA-CONTA
               WHEN DFHPF3    PERFORM 9900-ENCERRA
               WHEN DFHCLEAR  PERFORM 1000-ENVIA-TELA-ENTRADA
               WHEN OTHER
                   MOVE 'TECLA INVALIDA' TO MSGO
                   PERFORM 1000-ENVIA-TELA-ENTRADA
           END-EVALUATE.

       3000-PROCESSA-CONTA.
           MOVE CONTAI TO CA-NR-CONTA   *campo digitado pelo usuário
                 * … busca DB2, monta resposta …
           MOVE CA-NOME  TO NOMEO
           MOVE WS-SALDO-EDIT TO SALDOO
           MOVE 'CONSULTA REALIZADA COM SUCESSO' TO MSGO

           EXEC CICS SEND MAP('MPCONSUL')
                         MAPSET('MSCONSUL')
                         FROM(MPCONSULO)
                         DATAONLY       *envia só dados, não relayout
                         RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP.

✅ ERASE vs DATAONLY

  • ERASE — limpa a tela inteira antes de enviar o mapa. Use na primeira exibição ou quando quer redesenhar tudo.
  • DATAONLY — envia apenas os campos de dados, sem reenviar labels e bordas do mapa. Mais eficiente para atualizar só parte da tela.
  • Sem nenhuma opção — envia o mapa completo sobrepondo a tela atual sem limpar primeiro.

7. RESP e EIBRESP — tratando erros

Cada comando EXEC CICS pode gerar uma condição de erro. O mecanismo moderno usa a opção RESP para capturar o código e DFHRESP para comparar:

COBOL Padrão de tratamento com RESP
       WORKING-STORAGE SECTION.
       01  WS-RESP   S9(08) COMP.
       01  WS-RESP2  S9(08) COMP.

       PROCEDURE DIVISION.

           EXEC CICS READ
               FILE('CONTA')
               INTO(WS-REG-CONTA)
               RIDFLD(WS-NR-CONTA)
               LENGTH(200)
               RESP(WS-RESP)
               RESP2(WS-RESP2)
           END-EXEC

           EVALUATE TRUE
               WHEN WS-RESP = DFHRESP(NORMAL)
                   PERFORM 2000-PROCESSA
               WHEN WS-RESP = DFHRESP(NOTFND)
                   MOVE 'CONTA NAO ENCONTRADA' TO MSGO
                   PERFORM 1000-ENVIA-TELA-ENTRADA
               WHEN OTHER
                   PERFORM 9900-ERRO-CICS
           END-EVALUATE.

       9000-TRATA-RESP.
           IF WS-RESP NOT = DFHRESP(NORMAL)
               PERFORM 9900-ERRO-CICS
           END-IF.

       9900-ERRO-CICS.
           EXEC CICS SEND TEXT
               FROM(WS-MSG-ERRO)
               LENGTH(80)
               ERASE
               FREEKB
           END-EXEC
           EXEC CICS RETURN END-EXEC.  *sem TRANSID = encerra a transação
DFHRESP Quando ocorre Comando típico
NORMALSucessoTodos
NOTFNDRegistro não encontradoREAD, DELETE
DUPRECChave duplicadaWRITE
LENGERRTamanho de campo erradoREAD, WRITE, SEND
MAPFAILNenhum dado digitado pelo usuárioRECEIVE MAP
PGMIDERRPrograma não encontrado no CSDLINK, XCTL
DISABLEDArquivo desabilitado no CICSREAD, WRITE
INVREQRequisição inválida para o recursoVários

No CICS, você não usa CALL para chamar outro programa — usa EXEC CICS LINK ou EXEC CICS XCTL:

COBOL LINK vs XCTL
             * LINK — chama e retorna (como CALL)
             * O programa chamado termina com EXEC CICS RETURN (sem TRANSID)
             * O controle volta para a próxima linha depois do LINK
           EXEC CICS LINK
               PROGRAM('PGMVALID')
               COMMAREA(WS-COMMAREA)
               LENGTH(117)
               RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP
                 * Retorna aqui após PGMVALID terminar
           IF CA-RETORNO = 'OK'
               PERFORM 3000-PROCESSA
           END-IF

             * XCTL — transfere controle (como GO TO entre programas)
             * O programa atual termina; PGMMENU assume o controle
             * Não há retorno para o programa que fez XCTL
           EXEC CICS XCTL
               PROGRAM('PGMMENU')
               COMMAREA(WS-COMMAREA)
               LENGTH(117)
               RESP(WS-RESP)
           END-EXEC.

9. Lendo e gravando VSAM via CICS

No CICS, arquivos VSAM não são abertos com OPEN — eles são definidos no CSD (CICS System Definition) e acessados com comandos EXEC CICS READ/WRITE/REWRITE/DELETE:

COBOL READ, WRITE, REWRITE e DELETE via CICS
       WORKING-STORAGE SECTION.
       01  WS-REG-CONTA  PIC X(200).
       01  WS-NR-CONTA   PIC X(10).
       01  WS-LEN        S9(04) COMP VALUE 200.

       PROCEDURE DIVISION.

       3000-LE-CONTA.
           EXEC CICS READ
               FILE('CONTA')          *nome no CSD
               INTO(WS-REG-CONTA)
               RIDFLD(WS-NR-CONTA)  *campo chave
               LENGTH(WS-LEN)
               RESP(WS-RESP)
           END-EXEC.

       4000-LE-ATUALIZA.
           EXEC CICS READ
               FILE('CONTA')
               INTO(WS-REG-CONTA)
               RIDFLD(WS-NR-CONTA)
               LENGTH(WS-LEN)
               UPDATE                 *bloqueia para atualização
               RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP

                 * modifica WS-REG-CONTA…

           EXEC CICS REWRITE
               FILE('CONTA')
               FROM(WS-REG-CONTA)
               LENGTH(WS-LEN)
               RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP.

       5000-INCLUI-CONTA.
           EXEC CICS WRITE
               FILE('CONTA')
               FROM(WS-REG-CONTA)
               RIDFLD(WS-NR-CONTA)
               LENGTH(WS-LEN)
               RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP.

       6000-EXCLUI-CONTA.
           EXEC CICS DELETE
               FILE('CONTA')
               RIDFLD(WS-NR-CONTA)
               RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP.

⚠️ READ UPDATE sem REWRITE causa deadlock

Quando você faz READ … UPDATE, o CICS bloqueia o registro. Se o programa terminar (via RETURN) sem ter feito REWRITE ou DELETE, o lock é liberado automaticamente. Mas se outra task tentar ler o mesmo registro com UPDATE enquanto o lock existe, ela ficará esperando — podendo gerar um AKCS (deadlock timeout). Sempre complete o ciclo READ UPDATE → REWRITE/DELETE no mesmo ciclo da transação.

10. Exemplo completo

O programa PGMCONS implementa uma consulta de saldo pseudo-conversacional completa: primeira vez exibe tela vazia, retorno do usuário lê a conta no DB2, exibe saldo formatado ou mensagem de erro:

COBOL PGMCONS — consulta de saldo CICS com DB2
      *----------------------------------------------------------------
      * PGMCONS — consulta de saldo (transação CONS)
      *----------------------------------------------------------------
       IDENTIFICATION DIVISION.
           PROGRAM-ID. PGMCONS.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
           EXEC SQL INCLUDE SQLCA     END-EXEC
           COPY DFHEIBLK.
           COPY DFHAID.
           COPY MPCONSUL.    *mapa BMS (gera MPCONSULI e MPCONSULO)
           COPY DCCONTA.     *DCLGEN da tabela CONTA

       01  WS-RESP         S9(08) COMP.
       01  WS-SALDO-EDIT   Z.ZZZ.ZZZ,99-.

       01  WS-COMMAREA.
           05  CA-FASE        PIC X(02).
           05  CA-NR-CONTA    PIC X(10).

       LINKAGE SECTION.
       01  DFHCOMMAREA.
           05  CA-FASE        PIC X(02).
           05  CA-NR-CONTA    PIC X(10).

       PROCEDURE DIVISION.

       0000-INICIO.
           IF EIBCALEN = 0
               INITIALIZE WS-COMMAREA
               MOVE '01' TO CA-FASE
           ELSE
               MOVE DFHCOMMAREA TO WS-COMMAREA
           END-IF

           EVALUATE CA-FASE
               WHEN '01'  PERFORM 1000-TELA-INICIAL
               WHEN '02'  PERFORM 2000-PROCESSA-ENTRADA
           END-EVALUATE

           EXEC CICS RETURN
               TRANSID(EIBTRNID)
               COMMAREA(WS-COMMAREA)
               LENGTH(12)
           END-EXEC.

       1000-TELA-INICIAL.
           INITIALIZE MPCONSULO
           MOVE 'INFORME O NUMERO DA CONTA' TO MSGO
           MOVE '02' TO CA-FASE
           EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
               FROM(MPCONSULO) ERASE CURSOR RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP.

       2000-PROCESSA-ENTRADA.
           EVALUATE EIBAID
               WHEN DFHPF3
                   EXEC CICS RETURN END-EXEC
               WHEN DFHENTER
                   CONTINUE
               WHEN OTHER
                   MOVE 'USE ENTER OU PF3' TO MSGO
                   EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
                       FROM(MPCONSULO) DATAONLY RESP(WS-RESP)
                   END-EXEC
                   PERFORM 9000-TRATA-RESP
                   STOP RUN
           END-EVALUATE

           EXEC CICS RECEIVE MAP('MPCONSUL') MAPSET('MSCONSUL')
               INTO(MPCONSULI) RESP(WS-RESP)
           END-EXEC
           IF WS-RESP = DFHRESP(MAPFAIL)
               MOVE 'INFORME O NUMERO DA CONTA' TO MSGO
               EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
                   FROM(MPCONSULO) DATAONLY RESP(WS-RESP)
               END-EXEC
               STOP RUN
           END-IF
           PERFORM 9000-TRATA-RESP

           MOVE CONTAI TO CA-NR-CONTA
           PERFORM 3000-BUSCA-DB2.

       3000-BUSCA-DB2.
           EXEC SQL
               SELECT NM_TITULAR, VL_SALDO, CD_STATUS
                 INTO :NM-TITULAR, :VL-SALDO, :CD-STATUS
                 FROM SCHEMA1.CONTA
                WHERE NR_CONTA = :CA-NR-CONTA
           END-EXEC

           EVALUATE TRUE
               WHEN SQLCODE = 0
                   MOVE NM-TITULAR-TEXT TO NOMEO
                   MOVE VL-SALDO TO WS-SALDO-EDIT
                   MOVE WS-SALDO-EDIT TO SALDOO
                   MOVE 'CONSULTA REALIZADA' TO MSGO
               WHEN SQLCODE = +100
                   MOVE 'CONTA NAO ENCONTRADA' TO MSGO
               WHEN OTHER
                   MOVE 'ERRO AO CONSULTAR BANCO DE DADOS' TO MSGO
           END-EVALUATE

           EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
               FROM(MPCONSULO) DATAONLY CURSOR RESP(WS-RESP)
           END-EXEC
           PERFORM 9000-TRATA-RESP
           MOVE '01' TO CA-FASE.   *próximo Enter = nova consulta

       9000-TRATA-RESP.
           IF WS-RESP NOT = DFHRESP(NORMAL)
               EXEC CICS ABEND ABCODE('CSER') END-EXEC
           END-IF.

11. Erros comuns e abends CICS

Abends CICS mais frequentes

Abend Causa Como corrigir
ASRAProgram check (S0C7, S0C4 etc.) dentro da task CICSAnalisar CEEDUMP com offset da instrução falha
AICALoop infinito — task excedeu runaway intervalEncontrar e corrigir o PERFORM sem saída
AKCSDeadlock — timeout aguardando recurso bloqueadoRevisar ordem de locks; usar READ UPDATE apenas quando necessário
AFCAErro de acesso a arquivo VSAMVerificar RESP/RESP2 e definição do arquivo no CSD
AEXNEXEC CICS ABEND chamado pelo programaVer ABCODE gerado pelo programa para identificar ponto
AEY9DB2 não disponível ou não conectado à region CICSVerificar attachment DB2/CICS e nome do plan

1. Usar STOP RUN em programa CICS

COBOLSTOP RUN no CICS causa abend ASRA
             * ❌ STOP RUN encerra a região CICS inteira — não use!
           IF WS-ERRO
               STOP RUN

             * ✅ Encerre com EXEC CICS RETURN (sem TRANSID p/ fechar task)
           IF WS-ERRO
               EXEC CICS SEND TEXT FROM(WS-MSG) LENGTH(80)
                   ERASE END-EXEC
               EXEC CICS RETURN END-EXEC

2. OPEN/CLOSE de arquivo no CICS

COBOLOPEN/CLOSE não é válido no CICS
             * ❌ Comandos COBOL nativos de arquivo não funcionam no CICS
           OPEN INPUT ARQ-CONTA
           READ ARQ-CONTA INTO WS-REG

             * ✅ Use EXEC CICS READ com nome do arquivo definido no CSD
           EXEC CICS READ FILE('CONTA') INTO(WS-REG)
               RIDFLD(WS-CHAVE) LENGTH(200) RESP(WS-RESP)
           END-EXEC

3. Working-Storage não persiste — usar COMMAREA

COBOLDado perdido entre ciclos
       WORKING-STORAGE SECTION.
       01  WS-CONTA-PESQ  PIC X(10) VALUE SPACES.

       PROCEDURE DIVISION.
                 * 1o ciclo: usuário informa conta '1234567890'
           MOVE CONTAI TO WS-CONTA-PESQ   *guardou na WS
           EXEC CICS RETURN TRANSID('CONS') END-EXEC

                 * 2o ciclo: WS-CONTA-PESQ = SPACES! (reiniciou)
                 * ❌ Dado perdido entre ciclos

             * ✅ Grave na COMMAREA antes do RETURN:
           MOVE CONTAI TO CA-NR-CONTA
           EXEC CICS RETURN TRANSID('CONS')
               COMMAREA(WS-COMMAREA) LENGTH(12)
           END-EXEC

4. MAPFAIL não tratado causa ASRA

COBOLUsuário pressiona PF sem digitar → MAPFAIL
           EXEC CICS RECEIVE MAP('MPCONSUL') MAPSET('MSCONSUL')
               INTO(MPCONSULI) RESP(WS-RESP)
           END-EXEC
                 * ❌ Se não checar MAPFAIL e tentar usar MPCONSULI, pode ASRA
           MOVE CONTAI TO CA-NR-CONTA

                 * ✅ Trate MAPFAIL antes de usar os campos do mapa
           IF WS-RESP = DFHRESP(MAPFAIL)
               MOVE 'PREENCHA OS CAMPOS OBRIGATORIOS' TO MSGO
               PERFORM 1000-REENVIA-TELA
               STOP RUN
           END-IF