☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta z/OS. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta z/OS. Mostrar todas as mensagens

segunda-feira, 14 de setembro de 2026

💳 BELLACARD — Como seria um sistema de cartões de crédito dentro de um IBM Mainframe?

 

Bellacosa Mainframe e o processamento do cartão de credito

☕ Um Café no Bellacosa Mainframe

💳 BELLACARD — Como seria um sistema de cartões de crédito dentro de um IBM Mainframe?

Do “BIP!” da maquininha ao COBOL, CICS, Db2, MQ, JCL, RACF, criptografia, antifraude, clearing, settlement e bilhões de transações que ninguém percebe.

Imagine a cena.

Você entra numa cafeteria, pede um café, aproxima o cartão da maquininha e...

BIP!

TRANSAÇÃO APROVADA
R$ 17,50

Você guarda o cartão, pega o café e continua a vida.

Talvez tenham se passado dois segundos.

Para o consumidor, acabou.

Para um programador mainframe curioso, porém, aconteceu uma pequena maravilha tecnológica.

Aqueles poucos segundos podem envolver terminal de pagamento, adquirente, rede de cartões, banco emissor, sistemas de autorização, criptografia, verificação do cartão, consulta de limites, regras de segurança, sistemas antifraude, bancos de dados, logs, mensagens entre plataformas e uma resposta que precisa percorrer boa parte desse caminho no sentido contrário.

E ainda não acabou.

Mais tarde haverá processamento financeiro, clearing, settlement, conciliação, lançamento da compra, fechamento da fatura, eventual parcelamento, pagamento, contabilização, estorno, contestação e talvez até um chargeback.

A humilde compra do café abriu uma pequena saga computacional.

E é exatamente por isso que cartões de crédito são um excelente laboratório para entender por que mainframes existem.

Então coloque café na caneca.

Hoje construiremos mentalmente o:

💳 BELLACARD — Credit Card Processing System for z/OS



Não será o projeto real de nenhum banco ou bandeira. Será uma arquitetura didática para entendermos como tecnologias como COBOL, CICS, Db2, MQ, JCL/JES2, RACF, criptografia, SMF, WLM e Parallel Sysplex podem participar de um grande sistema financeiro.



🏪 Capítulo 1 — Tudo começa com R$ 100

Imagine uma compra:

CLIENTE:       JOÃO
VALOR:         R$ 100,00
ESTABELECIMENTO: CAFÉ DO MAINFRAME
FORMA:         CARTÃO

O cartão é apresentado.

A maquininha não conhece necessariamente o saldo da conta do cliente.

O estabelecimento também não.

A adquirente não é necessariamente quem concedeu o crédito.

Existe uma cadeia.

Simplificando:

CARDHOLDER
    │
    ▼
MERCHANT
    │
    ▼
ACQUIRER
    │
    ▼
CARD NETWORK
    │
    ▼
ISSUER

Visa e Mastercard, por exemplo, operam redes que conectam os participantes do ecossistema.

O banco emissor é quem conhece o cartão, sua situação, conta relacionada, limite e diversas regras necessárias para decidir se aquela operação pode prosseguir.

Portanto, eventualmente surge uma pergunta:

“Banco, você autoriza esta compra?”

É aí que nosso BELLACARD acorda.



📨 Capítulo 2 — Uma mensagem bate à porta

Imagine que recebamos uma representação simplificada da operação:

TRANSACTION TYPE : PURCHASE
CARD TOKEN        : 987654321
AMOUNT            : 100.00
CURRENCY          : BRL
MERCHANT ID       : 785932
MCC               : 5812
COUNTRY            : BRA
ENTRY MODE         : CONTACTLESS
DATE               : 20260914
TIME               : 031700

Sim.

03:17.

Quem acompanha o Bellacosa Mainframe sabe que esse horário nunca aparece por acidente.

😏

Nosso primeiro easter egg já foi registrado.

Em sistemas reais, mensagens de cartões podem utilizar padrões e protocolos próprios do setor, incluindo famílias baseadas em ISO 8583, além de APIs e formatos modernos dependendo da integração.

Para nosso iniciante COBOL, entretanto, vamos imaginar simplesmente um registro chegando ao mainframe.



🖥️ Capítulo 3 — CICS, atenda a porta!

Dentro do z/OS poderíamos possuir uma transação CICS:

AUTH

Sua missão:

processar uma solicitação de autorização.

Conceitualmente:

REQUEST
   │
   ▼
 CICS
   │
   ▼
AUTHORIZATION PROGRAM
   │
   ├── VALIDATE CARD
   ├── CHECK STATUS
   ├── CHECK LIMIT
   ├── CHECK RULES
   ├── CHECK RISK
   │
   ▼
APPROVE / DECLINE

Um pseudocódigo COBOL extremamente simplificado poderia parecer:

       PROCEDURE DIVISION.

           PERFORM VALIDATE-REQUEST
           PERFORM READ-CARD
           PERFORM CHECK-CARD-STATUS
           PERFORM CHECK-AVAILABLE-LIMIT
           PERFORM CHECK-RISK

           IF WS-AUTHORIZED
               PERFORM CREATE-AUTHORIZATION
               PERFORM RESERVE-LIMIT
               MOVE '00' TO WS-RESPONSE-CODE
           ELSE
               MOVE '05' TO WS-RESPONSE-CODE
           END-IF.

Não copie isso para instalar amanhã no banco. 😁

Estamos construindo um modelo didático.

O importante é compreender o fluxo.


💳 Capítulo 4 — O cartão existe?

Nossa primeira pergunta parece ridícula:

O cartão existe?

Mas sistemas robustos começam validando o básico.

Podemos possuir algo conceitualmente semelhante a:

CARD
---------------------------
CARD_ID
ACCOUNT_ID
CARD_TOKEN
STATUS
EXPIRATION_DATE
PRODUCT_CODE
BLOCK_CODE

O programa consulta:

SELECT STATUS,
       ACCOUNT_ID,
       EXPIRATION_DATE
FROM CARD
WHERE CARD_TOKEN = :WS-CARD-TOKEN

E descobre:

STATUS = ACTIVE

Ótimo.

Mas poderia encontrar:

BLOCKED
CANCELLED
EXPIRED
LOST
STOLEN

Nesse caso, dependendo das regras:

DECLINED

Observe algo importante para quem está aprendendo COBOL.

O programa não está simplesmente “fazendo contas”.

Ele está implementando regras de negócio.

Essa é uma das essências do COBOL empresarial.


🏦 Capítulo 5 — A conta e o limite

Encontramos a conta:

ACCOUNT_ID       = 100238
CREDIT_LIMIT     = 10000.00
AVAILABLE_LIMIT  = 5800.00
CURRENT_BALANCE  = 3400.00
PENDING_AUTH     = 800.00

A compra solicitada é:

100.00

Temos limite.

Mas cuidado.

Não deveríamos simplesmente fazer:

SUBTRACT 100 FROM AVAILABLE-LIMIT.

Por quê?

Porque provavelmente existem milhares de transações concorrentes.

Imagine duas compras quase simultâneas.

AVAILABLE LIMIT = R$ 500

COMPRA A = R$ 400
COMPRA B = R$ 400

Dois programas consultam:

R$ 500 disponível.

A conclui:

aprovado.

B conclui:

aprovado.

Parabéns.

Acabamos de autorizar R$ 800 usando R$ 500.

Bem-vindo ao maravilhoso universo da concorrência transacional.


🔒 Capítulo 6 — COMMIT e ROLLBACK não são frescura

Aqui começamos a compreender por que sistemas transacionais possuem mecanismos tão sofisticados.

Nossa operação poderia ser tratada como uma Unit of Work.

BEGIN UOW
    │
    ├── READ ACCOUNT
    │
    ├── CHECK LIMIT
    │
    ├── CREATE AUTHORIZATION
    │
    ├── RESERVE LIMIT
    │
    └── WRITE AUDIT
           │
           ▼
         COMMIT

Mas imagine:

CREATE AUTHORIZATION → OK
RESERVE LIMIT        → OK
WRITE SOMETHING      → ERROR

Não podemos deixar metade da operação concluída.

Precisamos de:

ROLLBACK

A ideia fundamental é:

Ou a unidade lógica de trabalho acontece de maneira consistente, ou voltamos ao estado apropriado.

Esse é um dos conceitos que um programador COBOL iniciante deveria tatuar mentalmente.

Em aplicações financeiras, inconsistência pode significar dinheiro.


🧠 Capítulo 7 — O limite existe, mas devemos autorizar?

Não necessariamente.

Imagine:

LIMITE DISPONÍVEL: R$ 20.000
COMPRA:            R$ 7.000

Matematicamente:

7000 < 20000

Então aprova?

Talvez.

Agora acrescente:

CLIENTE NORMALMENTE COMPRA: Brasil
HORÁRIO:                     03:17
VALOR MÉDIO:                 R$ 80
COMPRA ATUAL:                R$ 7.000
PAÍS:                        outro país
MERCHANT:                    desconhecido

🚨

Entra o Risk/Fraud Engine.


🚨 Capítulo 8 — O Sherlock Holmes das transações

O sistema antifraude pode observar dezenas ou centenas de sinais.

Por exemplo:

VALUE
TIME
COUNTRY
MERCHANT
MCC
DEVICE
TRANSACTION VELOCITY
HISTORICAL BEHAVIOR
AUTHENTICATION
PREVIOUS DECLINES
GEOGRAPHICAL PATTERNS

Imagine:

23:10 São Paulo
R$ 37,50

23:18 São Paulo
R$ 83,00

23:22 Tokyo
R$ 9.700

Não precisamos ser Hercule Poirot para levantar uma sobrancelha.

Nosso sistema poderia calcular:

RISK SCORE = 947

E possuir regras como:

000-300   LOW
301-700   MEDIUM
701-850   HIGH
851-1000  DECLINE/REVIEW

Atualmente esse ambiente pode combinar regras determinísticas, estatística, análise comportamental e machine learning.

Mas COBOL continua perfeitamente capaz de executar regras determinísticas essenciais.

IF WS-RISK-SCORE > 850
    MOVE 'N' TO WS-AUTHORIZED
END-IF.

Às vezes não precisamos de inteligência artificial.

Precisamos apenas de:

IF COISA-ABSURDA
   NÃO-FAÇA
END-IF

Uma tecnologia revolucionária conhecida desde tempos imemoriais como bom senso programado.


⚡ Capítulo 9 — Tudo isso precisa ser rápido

Esse é um requisito extraordinário.

O consumidor está esperando.

Ele não quer ver:

PROCESSANDO...

PROCESSANDO...

PROCESSANDO...

enquanto o sistema gera um relatório gerencial de 400 páginas.

Por isso workloads diferentes possuem prioridades diferentes.

Entra o WLM — Workload Manager.

Conceitualmente:

AUTHORIZATION     CRITICAL
PAYMENT           HIGH
CUSTOMER QUERY    HIGH
REPORTING         MEDIUM
ANALYTICS BATCH   LOWER

Quando existe competição por recursos, o sistema operacional precisa compreender que:

autorizar a compra do cliente é mais urgente do que imprimir o relatório do chefe.

Embora alguns chefes possam discordar.


📨 Capítulo 10 — MQ: nem todo mundo precisa esperar

Imagine que a compra foi aprovada.

Precisamos responder imediatamente.

Mas também queremos:

  • registrar eventos;

  • enviar notificação;

  • alimentar analytics;

  • avisar sistemas antifraude;

  • atualizar outros ambientes;

  • produzir informações para aplicações móveis.

Seria absurdo fazer o consumidor esperar tudo isso.

Então:

CICS AUTH
    │
    ├──────────────► RESPONSE
    │
    │
    └──────────────► MQ
                         │
               ┌─────────┼─────────┐
               ▼         ▼         ▼
             FRAUD    ANALYTICS   ALERT
                                   │
                                   ▼
                           "Compra aprovada"

Aqui aparece uma das grandes ideias de arquitetura:

separe o caminho crítico das tarefas que podem acontecer assincronamente.

IBM MQ encaixa-se maravilhosamente nesse tipo de integração.


🧾 Capítulo 11 — APPROVED não significa “acabou”

Esse é provavelmente um dos conceitos mais interessantes do sistema.

A compra foi autorizada:

AUTHORIZATION

VALUE  = 100.00
STATUS = PENDING

Mas autorização e lançamento financeiro definitivo são coisas diferentes.

Posteriormente chegam informações financeiras que precisam ser conciliadas com aquela autorização.

Simplificando:

AUTHORIZATION
      │
      ▼
PRESENTMENT
      │
      ▼
MATCHING
      │
      ▼
POSTING

Finalmente:

POSTED TRANSACTION

Por que essa separação?

Porque o mundo real é bagunçado.


🏨 Capítulo 12 — O hotel de R$ 1.000 que virou R$ 873,42

Você chega a um hotel.

Pode ocorrer uma autorização inicial:

R$ 1.000

Sua conta final acaba sendo:

R$ 873,42

Agora nosso sistema precisa compreender que existe relacionamento entre as operações.

Situações semelhantes aparecem em:

  • hotéis;

  • locadoras;

  • restaurantes;

  • postos;

  • cancelamentos;

  • ajustes;

  • estornos.

Portanto:

AUTHORIZATION ≠ FINAL TRANSACTION

Esse é um daqueles detalhes que parecem insignificantes até você precisar construir o sistema.

Então tornam-se gigantescos.


📦 Capítulo 13 — E das profundezas surge o BATCH

Durante o dia, imagine:

CICS
CICS
CICS
CICS
CICS
CICS
CICS

Transações chegando continuamente.

Em paralelo ou em determinados ciclos, precisamos executar processamento massivo.

Entra:

JES2 + JCL + COBOL Batch

Poderíamos possuir uma cadeia didática:

RECEIVE CLEARING
       │
       ▼
VALIDATE
       │
       ▼
MATCH AUTHORIZATION
       │
       ▼
POST TRANSACTION
       │
       ▼
UPDATE ACCOUNT
       │
       ▼
BILLING
       │
       ▼
SETTLEMENT
       │
       ▼
RECONCILIATION

Um JCL fictício:

//BELCARD JOB ...
//STEP010 EXEC PGM=BCLR001
//STEP020 EXEC PGM=BVAL001
//STEP030 EXEC PGM=BMAT001
//STEP040 EXEC PGM=BPOS001
//STEP050 EXEC PGM=BBIL001
//STEP060 EXEC PGM=BSET001

Cada programa possui responsabilidade específica.

Isso permite restart, controle, auditoria e operacionalização muito melhores do que construir um monstro chamado:

FAZTUDO.CBL

com 187 mil linhas.

Embora algum arqueólogo de sistemas provavelmente já tenha encontrado algo parecido.


🧮 Capítulo 14 — A fábrica de faturas

Chegamos ao billing.

Para cada conta precisamos considerar:

SALDO ANTERIOR
+
COMPRAS
+
PARCELAS
+
ENCARGOS
+
JUROS
-
PAGAMENTOS
-
CRÉDITOS
-
ESTORNOS
=
NOVO SALDO

Em COBOL:

COMPUTE WS-NEW-BALANCE =
        WS-PREVIOUS-BALANCE
      + WS-PURCHASES
      + WS-INSTALLMENTS
      + WS-FEES
      + WS-INTEREST
      - WS-PAYMENTS
      - WS-CREDITS.

E aqui COBOL está em casa.

Valores decimais, regras empresariais, processamento de registros e grandes volumes de dados são precisamente o tipo de problema para o qual COBOL nasceu.


🇧🇷 Capítulo 15 — A entidade brasileira chamada PARCELAMENTO

Agora compramos:

R$ 1.200 em 12x

Nosso sistema registra:

PURCHASE_ID = 9838172
TOTAL       = 1200.00
QTY         = 12

E teremos:

01/12  100
02/12  100
03/12  100
...
12/12  100

Parece simples.

Até alguém perguntar:

“E se houver estorno na parcela 7?”

Ou:

“E se for estorno parcial?”

Ou:

“E se o cliente contestar a compra?”

Ou:

“E se houver renegociação?”

Ou:

“E se existir juros?”

Ou:

“E se o comerciante fizer refund?”

É assim que programas pequenos envelhecem e viram programas COBOL de 30 mil linhas.

Não necessariamente porque os programadores antigos eram malucos.

Frequentemente porque 30 anos de realidade foram sendo incorporados ao código.

Essa é uma lição importantíssima para quem entra hoje no mainframe.

Código legado muitas vezes é também:

regra de negócio fossilizada.

Não apague antes de descobrir por que existe.


🔐 Capítulo 16 — RACF: não, estagiário, você não pode consultar todos os cartões

Nosso BELLACARD contém informações extremamente sensíveis.

Precisamos controlar:

WHO
CAN DO WHAT
TO WHICH RESOURCE
UNDER WHICH CONDITIONS

RACF pode participar do controle de acesso ao ambiente z/OS.

Podemos proteger datasets, transações, usuários, grupos e diversos recursos.

Conceitualmente:

USER VAGNER
    │
    ├── AUTH → READ/EXECUTE
    ├── BILL → READ
    └── ADMIN → NO ACCESS

O princípio essencial é:

LEAST PRIVILEGE.

Um programa deve possuir apenas os acessos necessários.

Um operador também.

Um desenvolvedor também.

E definitivamente ninguém deveria possuir acesso porque:

“Vai que um dia eu precise.”


🔑 Capítulo 17 — E as chaves criptográficas?

Agora entramos em território ainda mais sensível.

Cartões envolvem criptografia, autenticação, tokens, PINs e material criptográfico.

A regra de ouro é:

chaves críticas não devem virar variáveis COBOL espalhadas pela aplicação.

Algo como:

01 SUPER-SECRET-KEY PIC X(32)
   VALUE 'MINHACHAVE123...'.

é praticamente uma carta de demissão escrita em COBOL.

😂

Ambientes financeiros utilizam infraestrutura criptográfica especializada e HSMs — Hardware Security Modules — para determinadas operações e proteção de chaves.

A aplicação solicita uma operação criptográfica.

O segredo permanece protegido.


🕵️ Capítulo 18 — “Eu não fiz essa compra.”

Três meses depois o cliente telefona:

Eu nunca fiz essa compra.

O sistema precisa reconstruir o passado.

Queremos saber:

QUANDO?
QUAL CARTÃO?
QUAL MERCHANT?
QUAL VALOR?
QUAL CANAL?
QUAL RESPOSTA?
QUAL SISTEMA?
QUAL REGRA?
QUAL RESULTADO?

Logs e trilhas de auditoria tornam-se fundamentais.

No universo z/OS, SMF e informações produzidas pelos subsistemas ajudam a construir observabilidade e auditoria.

Nosso sistema deveria conseguir reconstruir algo como:

03:17:00.103 REQUEST RECEIVED
03:17:00.108 CARD VALIDATED
03:17:00.112 STATUS ACTIVE
03:17:00.119 LIMIT OK
03:17:00.127 RISK SCORE 214
03:17:00.133 AUTH CREATED
03:17:00.139 LIMIT RESERVED
03:17:00.145 COMMIT
03:17:00.151 APPROVED

E aí descobrimos outra característica dos sistemas financeiros:

não basta fazer certo. Precisamos conseguir demonstrar posteriormente o que aconteceu.


🏰 Capítulo 19 — E se o mainframe cair?

Imagine milhões de pessoas tentando pagar almoço e recebendo:

HOST UNAVAILABLE

O problema deixa rapidamente de ser “um incidente de TI”.

Vira problema comercial, financeiro e reputacional.

Daí entram conceitos de alta disponibilidade e arquiteturas como Parallel Sysplex.

Didaticamente:

                 REQUESTS
                     │
                     ▼
               WORKLOAD ROUTING
                     │
          ┌──────────┴──────────┐
          ▼                     ▼
       z/OS A                 z/OS B
        CICS                   CICS
          │                     │
          └──────────┬──────────┘
                     ▼
                   Db2
               Data Sharing

Falhou um componente?

A arquitetura é desenhada para evitar que isso necessariamente signifique:

TODO MUNDO PARA.

É aqui que redundância, recuperação, data sharing, workload management, automação operacional e engenharia de resiliência deixam de ser palavras bonitas de PowerPoint.


🏙️ Capítulo 20 — As duas cidades do cartão

Eu gosto de imaginar o BELLACARD dividido em duas grandes cidades.

⚡ Cidade Online

Seu prefeito é o CICS.

Sua pergunta principal:

POSSO COMPRAR?

REQUEST
   │
   ▼
CICS
   │
   ▼
CARD
LIMIT
RISK
RULES
   │
   ▼
YES / NO

Velocidade, disponibilidade e consistência dominam essa cidade.


🏭 Cidade Financeira

Aqui vivem:

Db2 + COBOL Batch + JES2 + MQ + sistemas contábeis.

Sua pergunta é diferente:

O QUE ACONTECEU COM O DINHEIRO?

AUTHORIZATION
      ↓
TRANSACTION
      ↓
POSTING
      ↓
ACCOUNT
      ↓
STATEMENT
      ↓
PAYMENT
      ↓
ACCOUNTING
      ↓
RECONCILIATION

Aqui cada centavo precisa encontrar seu destino.


🧩 Capítulo 21 — Afinal, onde cada tecnologia entra?

Agora nosso iniciante consegue enxergar o tabuleiro inteiro.

COBOL
│
├── business rules
├── authorization
├── billing
├── posting
└── batch processing

CICS
│
├── online transactions
├── transaction management
└── units of work

Db2
│
├── accounts
├── cards
├── authorizations
├── transactions
└── statements

MQ
│
├── asynchronous messaging
├── events
├── integration
└── notifications

JCL/JES2
│
├── batch
├── billing
├── reconciliation
└── settlement processing

RACF
│
└── access control

CRYPTO/HSM
│
└── sensitive cryptographic operations

SMF/MONITORING
│
├── auditing
└── observability

WLM
│
└── workload priorities

PARALLEL SYSPLEX
│
└── availability/scalability

Percebe a diferença?

Agora COBOL, CICS, Db2, MQ e JCL deixaram de ser matérias isoladas de um curso.

Cada tecnologia apareceu porque tínhamos um problema para resolver.

É assim que eu gosto de ensinar mainframe.


🎓 Capítulo 22 — Construindo o BELLACARD como projeto educacional

Eu transformaria essa arquitetura numa trilha prática.

O aluno começa pequeno.

Nível 1 — COBOL

Criar:

CUSTOMER
CARD
ACCOUNT

Depois:

PURCHASE
PAYMENT
LIMIT

Finalmente:

STATEMENT

Nível 2 — Arquivos

Guardar clientes e contas.

Começar sequencialmente.

Depois introduzir VSAM.

Agora o aluno entende por que acesso indexado importa.


Nível 3 — Db2

Migramos para:

CUSTOMER
ACCOUNT
CARD
AUTHORIZATION
TRANSACTION
PAYMENT
STATEMENT

Aprendemos:

SELECT
INSERT
UPDATE
DELETE
COMMIT
ROLLBACK

Não como comandos aleatórios de SQL.

Mas porque nosso banco precisa deles.


Nível 4 — CICS

Criamos:

AUTH = Authorization
ACCT = Account Inquiry
PAYM = Payment
BLCK = Block Card

Agora nosso COBOL deixou de ser apenas batch.

Temos um pequeno sistema transacional.


Nível 5 — MQ

A compra aprovada produz:

CARD.PURCHASE.APPROVED

Outro consumidor recebe.

Depois outro.

Aprendemos arquitetura assíncrona.


Nível 6 — Batch

Criamos:

POSTING
BILLING
PAYMENT PROCESSING
STATEMENT GENERATION
RECONCILIATION

Finalmente o aluno entende por que empresas ainda executam workloads batch gigantescos.


Nível 7 — Segurança

Introduzimos:

RACF
AUDIT
CRYPTOGRAPHY
TOKENIZATION

Agora nosso brinquedo começa a parecer uma plataforma empresarial.


Nível 8 — Operação

Provocamos problemas.

DB2 TIMEOUT
MQ QUEUE FULL
CICS ABEND
JOB RC=12
DATASET FULL
AUTHORIZATION LATENCY

E perguntamos:

O que o suporte N2 faria?

Depois:

E o N3?

Agora nasceu uma pequena War Room BELLACARD.


🔥 Capítulo 23 — O exercício mais importante: quebrar o sistema

Eu faria questão de criar erros propositalmente.

Por exemplo:

AVAILABLE LIMIT = 500

Disparamos simultaneamente:

PURCHASE A = 400
PURCHASE B = 400

Se ambas forem aprovadas incorretamente, descobrimos uma falha de concorrência.

Outro teste:

INSERT AUTHORIZATION = SUCCESS
UPDATE LIMIT         = FAILURE

O sistema ficou inconsistente?

Se sim:

faltou tratar corretamente a unidade de trabalho.

Outro:

MQ unavailable

A autorização precisa parar?

Talvez não.

Essa pergunta ensina arquitetura melhor que vinte slides.


👻 Capítulo 24 — O fantasma das 03:17

Chegamos ao easter egg.

Todos os dias exatamente às:

03:17

o BELLACARD começa a apresentar:

AUTH RESPONSE TIME
120ms
180ms
350ms
900ms
2.1s

Nenhum erro.

CPU normal.

Db2 aparentemente normal.

MQ normal.

CICS sem ABEND.

Mas a latência explode durante sete minutos.

Nosso programador iniciante recebe seu primeiro chamado:

INCIDENT #0317

SEVERITY: HIGH
DESCRIPTION:
Intermittent authorization latency.

Começa a investigação.

RMF.

SMF.

CICS statistics.

Db2 accounting.

WLM.

JES2.

Até descobrir...

Um antigo job chamado:

//MONSTR17 JOB

executado diariamente às 03:17, realizando uma consulta monstruosa contra tabelas utilizadas pelo sistema online.

O programa foi criado em 1997.

O comentário no topo:

      * DO NOT REMOVE.
      * BUSINESS REQUIREMENT.
      * JSMITH - 1997-04-13

Ninguém sabe quem é JSMITH.

Ninguém sabe qual era o requisito.

Mas todos têm medo de remover.

🤣

Bem-vindo ao mainframe corporativo.


🧠 Curiosidade — O verdadeiro patrimônio não é apenas o código

Esse é talvez o conhecimento mais importante de todo o artigo.

Quando alguém encontra um programa COBOL com milhares de linhas, pode pensar:

“Que coisa velha.”

Mas aquele programa pode conter décadas de:

  • regras;

  • exceções;

  • regulamentações;

  • incidentes;

  • fraudes descobertas;

  • produtos descontinuados;

  • produtos ainda ativos;

  • acordos comerciais;

  • tratamentos especiais;

  • correções;

  • conhecimento empresarial.

É quase arqueologia.

Um comentário de 1997 pode explicar por que determinada operação de 2026 ainda funciona.

Por isso modernização responsável começa com:

compreender antes de substituir.


🏛️ Capítulo 25 — O mainframe como cidade invisível

Voltamos finalmente à cafeteria.

Você aproximou o cartão.

BIP!

Apareceu:

APROVADO

Você levou seu café.

Talvez nunca pense novamente naquela transação.

Mas atrás daquele pequeno momento poderia existir conceitualmente uma cidade inteira:

                   💳 CARD
                      │
                      ▼
                 POS / APP
                      │
                      ▼
                  ACQUIRER
                      │
                      ▼
               CARD NETWORK
                      │
                      ▼
╔══════════════════════════════════════╗
║               IBM Z                  ║
║                                      ║
║              CICS                    ║
║                │                     ║
║       ┌────────┼────────┐            ║
║       ▼        ▼        ▼            ║
║     CARD     LIMIT     RISK          ║
║       │        │        │            ║
║       └────────┼────────┘            ║
║                ▼                     ║
║               Db2                    ║
║                │                     ║
║               MQ                     ║
║                                      ║
║   COBOL • JCL • JES2 • RACF • SMF   ║
║        WLM • CRYPTO • SYSPLEX        ║
╚══════════════════════════════════════╝
                      │
                      ▼
                   APPROVED

O consumidor viu:

APROVADO.

O mainframer vê:

arquitetura.


☕ Conclusão — o BIP que esconde uma catedral

Talvez essa seja uma das melhores maneiras de explicar mainframe para alguém que está começando.

Não comece dizendo:

“COBOL possui DIVISION, SECTION e PARAGRAPH.”

Comece dizendo:

“Você acabou de passar um cartão. Quer descobrir o que pode existir atrás daquele BIP?”

Então COBOL ganha propósito.

CICS ganha propósito.

Db2 ganha propósito.

MQ ganha propósito.

JCL ganha propósito.

RACF ganha propósito.

SMF ganha propósito.

WLM ganha propósito.

Parallel Sysplex ganha propósito.

O iniciante deixa de decorar siglas e começa a compreender problemas.

E tecnologia empresarial é exatamente isso:

uma coleção de soluções para problemas que ficaram grandes demais para serem resolvidos de qualquer jeito.

Da próxima vez que aproximar seu cartão e ouvir:

BIP!

talvez você enxergue algo diferente.

Não apenas uma compra.

Mas uma mensagem atravessando redes, chegando a sistemas que verificam identidade, estado, crédito e risco; uma unidade de trabalho sendo protegida; registros sendo preservados; eventos sendo produzidos; sistemas financeiros preparando o que acontecerá depois.

Tudo isso para devolver uma pequena palavra:

       ┌────────────────────────┐
       │                        │
       │       APPROVED         │
       │                        │
       │         RC=00          │
       │                        │
       └────────────────────────┘

E talvez exista, em algum canto de algum sistema que ninguém ousa desligar, um programa COBOL escrito décadas atrás, trabalhando silenciosamente para que seu café seja pago.

Sem aplausos.

Sem interface bonita.

Sem ninguém perceber.

Como tantas outras coisas no mainframe.

Porque a melhor infraestrutura é aquela que desaparece atrás do serviço que presta.

E enquanto o mundo vê apenas o BIP, nós sabemos que atrás dele pode existir uma verdadeira catedral transacional construída byte por byte, regra por regra e geração por geração de programadores.

Um Café no Bellacosa Mainframe

Onde até uma compra de R$ 17,50 pode acabar em CICS, Db2, COBOL e uma War Room às 03:17.



☕ Um Café no Bellacosa Mainframe

🕵️ The Mentalist no Mainframe — O Caso dos R$ 100 que Atravessaram um Sistema de Cartões

Entenda como uma compra de R$ 100 atravessa POS, adquirente, bandeira, emissor, autorização, plafond, clearing, settlement, cobrança, contabilidade e reconciliação em um ambiente bancário e mainframe.

💳 Como funciona uma transação de cartão de crédito?

Uma compra aparentemente simples percorre diversos participantes e sistemas. O cliente apresenta o cartão ao estabelecimento, a maquininha envia a transação ao adquirente, a rede encaminha a solicitação ao emissor e o banco verifica cartão, conta, produto, plafond, regras e risco antes de autorizar ou recusar.

Depois da autorização, a transação ainda pode passar por reversal, clearing, settlement, faturamento, cobrança, contabilização, reconciliação, disputa e chargeback.

Principais assuntos: IBM Mainframe, IBM Z, COBOL, CICS, Db2, cartões de crédito, POS, adquirente, emissor, autorização, plafond, clearing, settlement, tarifas, cobrança, contabilidade e reconciliação.

🔎 Ler o artigo original: The Mentalist no Mainframe

Bellacosa Mainframe — conteúdo educacional sobre IBM Z, COBOL, CICS, sistemas bancários e processamento de cartões.

terça-feira, 1 de setembro de 2026

🚨 Você ainda acha que COBOL é só MOVE, PERFORM e uma tela verde? Agosto provou que o mainframe continua muito mais vivo — e perigoso — do que muita gente imagina.

 

Bellacosa Mainframe e o resumo da atividade em Agosto de 2026

🚨 Você ainda acha que COBOL é só MOVE, PERFORM e uma tela verde? Agosto provou que o mainframe continua muito mais vivo — e perigoso — do que muita gente imagina.



Um desenvolvedor COBOL não precisa virar especialista em tudo de uma noite para a outra. Mas precisa entender o cenário onde seu programa trabalha: dados no Db2, transações no CICS, operações no z/OS, integrações modernas, segurança, nuvem, containers e, agora, Inteligência Artificial.

Durante agosto, o El Jefe Midnight Lunch publicou artigos para quem quer sair do modo “apenas mantenho programa legado” e enxergar o ecossistema completo do IBM Z.

Temos conversas sobre:

  • IA sem perfume de PowerPoint: limites, riscos, alucinações, automação e pensamento crítico;

  • COBOL, CICS e Db2 explicados com exemplos, incidentes e histórias que ajudam a fixar o conceito;

  • Kubernetes e arquitetura moderna traduzidos para quem conhece batch, JCL, transação e produção de verdade;

  • Red Team, golpes digitais, segurança e contas fantasmas;

  • casos reais de falhas, migrações e decisões técnicas que custaram caro;

  • curiosidades, cultura pop, humor e aquelas perguntas que normalmente não aparecem no treinamento oficial.

Porque aprender mainframe não é decorar comandos. É entender por que um S0C7, um -805, um ABEND, uma regra mal escrita ou uma mudança aparentemente pequena podem parar um processo inteiro.

Passe pelos artigos de agosto, escolha um tema que provoque sua curiosidade e venha tomar esse café. O mainframe continua processando o mundo — e ainda tem muito segredo escondido no spool.

🔗 https://eljefemidnightlunch.blogspot.com/2026/08/



Resumo de Agosto de 2026


https://dio.me/articles/voce-ainda-acha-que-cobol-e-so-legado-move-perform-e-uma-tela-verde-f6320bc08379


sábado, 29 de agosto de 2026

CRUD Walker — Quando Chuck Norris Auditou um Cadastro COBOL, Encontrou Cinquenta Clientes na WORKING-STORAGE e Descobriu que o UPDATE Fugiu Antes da Compilação

 

Bellacosa Mainframe 

☕ Um Café no Bellacosa Mainframe

CRUD Walker — Quando Chuck Norris Auditou um Cadastro COBOL, Encontrou Cinquenta Clientes na WORKING-STORAGE e Descobriu que o UPDATE Fugiu Antes da Compilação

Ou: o jovem padawan chamou o programa de CRUD, Chuck Norris contou apenas três letras, Igor tentou esconder os clientes dentro de um OCCURS e o mainframe perguntou onde estavam o arquivo, o FILE STATUS e o COMMIT



Prólogo — O cadastro que entrou no saloon com uma letra faltando

O programa compilava.

O menu aparecia.

Clientes podiam ser incluídos, consultados, listados e excluídos. Havia confirmação antes da exclusão, tratamento de opções inválidas e até reorganização da tabela depois que um registro era removido.

Igor olhou para a tela verde, ajeitou o chapéu e anunciou:

— Está pronto! Um CRUD completo de clientes em COBOL!

No fundo da sala, Chuck Norris levantou os olhos do relatório de compilação.

Não disse nada.

Apenas escreveu quatro letras no quadro:

C — CREATE
R — READ
U — UPDATE
D — DELETE

Depois examinou o menu:

1 - INCLUIR CLIENTE
2 - CONSULTAR CLIENTE
3 - LISTAR CLIENTES
4 - EXCLUIR CLIENTE
0 - SAIR

Chuck contou novamente.

Havia CREATE, READ e DELETE. O UPDATE não estava ali.

Igor tentou explicar que “listar” talvez pudesse ser considerado o U, mas o compilador pediu demissão antes de participar daquela discussão.

O projeto não era ruim. Pelo contrário: era um laboratório muito interessante para quem está aprendendo COBOL. Ele reunia estruturas de dados, controle de fluxo, validação, pesquisa, interação pelo terminal e manipulação de registros em memória.

Mas ainda era um CRD, não um CRUD completo.

A boa notícia é que acrescentar o UPDATE não exige demolir o programa. Exige amadurecer sua construção.

E é exatamente nessa evolução que aparecem algumas das lições mais valiosas do desenvolvimento corporativo.



1. Antes do código: o que significa CRUD?

CRUD é um acrônimo criado para representar as quatro operações fundamentais executadas sobre dados persistentes:

LetraPalavraOperação
CCreateCriar um registro
RReadLer ou consultar
UUpdateAlterar um registro existente
DDeleteExcluir um registro

Em um cadastro de clientes:

CREATE → cadastrar Paulo
READ   → consultar Paulo
UPDATE → mudar o telefone de Paulo
DELETE → remover ou inativar Paulo

Embora a sigla tenha ficado muito associada aos bancos de dados, essas operações podem ser simuladas em qualquer estrutura:

  • tabela OCCURS;

  • arquivo sequencial;

  • VSAM KSDS;

  • tabela Db2;

  • fila;

  • memória;

  • aplicação CICS;

  • serviço exposto por API.

O mecanismo muda, mas a intenção permanece.

No protótipo original, os clientes vivem dentro de uma tabela em memória. Isso permite estudar o comportamento do CRUD sem introduzir imediatamente JCL, arquivos, catálogos, VSAM, SQL, locks e unidades de trabalho.

É como aprender a estacionar em um pátio vazio antes de tentar fazê-lo na Avenida Paulista às seis da tarde.

Chuck Norris, naturalmente, estaciona o mainframe em uma vaga de motocicleta. Mas o jovem padawan deve começar com cinquenta registros.




2. Onde os clientes estão guardados?

A estrutura central do protótipo pode ser representada assim:

       01  WS-TABELA-CLIENTES.
           05 WS-CLIENTE OCCURS 50 TIMES.
              10 WS-CODIGO      PIC 9(05).
              10 WS-NOME        PIC X(40).
              10 WS-CPF         PIC X(11).
              10 WS-TELEFONE    PIC X(15).

O OCCURS 50 TIMES cria uma tabela com cinquenta posições.

Mas atenção: ele não cadastra cinquenta clientes.

Ele apenas reserva espaço para até cinquenta ocorrências da estrutura WS-CLIENTE.

Por isso, normalmente existe um contador:

       01  WS-CONTROLE.
           05 WS-TOTAL-CLIENTES     PIC 9(02) VALUE ZERO.
           05 WS-POSICAO            PIC 9(02) VALUE ZERO.
           05 WS-POSICAO-ENCONTRADA PIC 9(02) VALUE ZERO.

A tabela pode possuir cinquenta posições físicas, mas apenas as primeiras posições correspondentes a WS-TOTAL-CLIENTES são consideradas ocupadas.

Por exemplo:

PosiçãoCódigoNomeEstado
100001Ana MariaOcupada
200002Paulo HenriqueOcupada
300003Carla SouzaOcupada
4–50zeros/espaçosLivres

Nesse momento:

WS-TOTAL-CLIENTES = 03

O contador representa a fronteira entre o território ocupado e o deserto.

Se ele estiver incorreto, o programa poderá:

  • ignorar clientes válidos;

  • listar posições vazias;

  • sobrescrever registros;

  • pesquisar além da área útil;

  • tentar acessar uma ocorrência fora do limite.

Uma regra fundamental é:

0WS-TOTAL-CLIENTES500 \leq WS\text{-}TOTAL\text{-}CLIENTES \leq 50

Chuck Norris não ultrapassa o limite de uma tabela. A tabela aumenta o OCCURS quando percebe que ele chegou.



3. PIC: não é decoração, é contrato de dados

Um iniciante pode olhar para:

05 WS-CODIGO PIC 9(05).
05 WS-NOME   PIC X(40).

e pensar que PIC serve apenas para determinar o tamanho do campo.

Mas PICTURE descreve a natureza lógica do dado.

PIC 9(05)

significa um campo numérico com cinco posições.

PIC X(40)

significa um campo alfanumérico de quarenta posições.

Essa escolha deve refletir o significado do dado.

Código do cliente

Se o código sempre tiver cinco algarismos:

05 WS-CODIGO PIC 9(05).

Se puder aceitar letras:

05 WS-CODIGO PIC X(05).

CPF

O CPF contém números, mas não representa uma quantidade.

Não fazemos:

CPF + CPF
CPF / 2
média de CPF
juros sobre CPF

O CPF é um identificador. Por isso, uma representação alfanumérica costuma ser adequada:

05 WS-CPF PIC X(11).

Isso também preserva zeros à esquerda.

Telefone

Telefone também não é quantidade:

05 WS-TELEFONE PIC X(15).

Com PIC X, podemos admitir:

  • zeros à esquerda;

  • código internacional;

  • sinal +;

  • DDD;

  • diferentes tamanhos.

Uma curiosidade importante: dizer que um campo possui apenas dígitos não significa que ele deva ser numericamente armazenado. CEP, número de documento, código de barras e telefone são exemplos clássicos.

O dado pode parecer número sem ser matematicamente numérico.



4. O menu: onde EVALUATE controla o saloon

Uma aplicação textual normalmente apresenta as opções e recebe a escolha do usuário:

       1000-EXIBIR-MENU.
           DISPLAY "=============================="
           DISPLAY "       CADASTRO DE CLIENTES"
           DISPLAY "=============================="
           DISPLAY "1 - INCLUIR CLIENTE"
           DISPLAY "2 - CONSULTAR CLIENTE"
           DISPLAY "3 - LISTAR CLIENTES"
           DISPLAY "4 - ALTERAR CLIENTE"
           DISPLAY "5 - EXCLUIR CLIENTE"
           DISPLAY "0 - SAIR"
           DISPLAY "OPCAO: "
           ACCEPT WS-OPCAO.

Em seguida:

       1100-PROCESSAR-OPCAO.
           EVALUATE WS-OPCAO
               WHEN 1
                   PERFORM 2000-INCLUIR-CLIENTE
               WHEN 2
                   PERFORM 3000-CONSULTAR-CLIENTE
               WHEN 3
                   PERFORM 4000-LISTAR-CLIENTES
               WHEN 4
                   PERFORM 5000-ALTERAR-CLIENTE
               WHEN 5
                   PERFORM 6000-EXCLUIR-CLIENTE
               WHEN 0
                   MOVE "S" TO WS-FIM
               WHEN OTHER
                   DISPLAY "OPCAO INVALIDA"
           END-EVALUATE.

EVALUATE é apropriado porque o usuário escolhe uma alternativa entre várias possibilidades.

Seria possível usar vários IF, mas isso tornaria o fluxo menos legível:

IF WS-OPCAO = 1
   ...
ELSE
   IF WS-OPCAO = 2
      ...
   ELSE
      IF WS-OPCAO = 3

Depois de alguns níveis, Igor precisaria de um mapa, uma lanterna e uma autorização do RACF para encontrar o END-IF correto.



5. Nível 88: quando o número ganha significado

O COBOL permite associar nomes semânticos aos valores:

       01  WS-OPCAO                 PIC 9.
           88 OP-INCLUIR            VALUE 1.
           88 OP-CONSULTAR          VALUE 2.
           88 OP-LISTAR             VALUE 3.
           88 OP-ALTERAR            VALUE 4.
           88 OP-EXCLUIR            VALUE 5.
           88 OP-SAIR               VALUE 0.
           88 OPCAO-VALIDA          VALUE 0 THRU 5.

Agora é possível escrever:

       IF NOT OPCAO-VALIDA
           DISPLAY "OPCAO INVALIDA"
       END-IF

Em vez de perguntar “o valor está entre zero e cinco?”, o programa pergunta “a opção é válida?”.

Esse é um dos poderes discretos do COBOL: aproximar o código da linguagem do negócio.

Outro exemplo:

       01  WS-ENCONTRADO            PIC X VALUE "N".
           88 CLIENTE-ENCONTRADO    VALUE "S".
           88 CLIENTE-NAO-ENCONTRADO VALUE "N".

Então:

       IF CLIENTE-ENCONTRADO
           DISPLAY "CLIENTE LOCALIZADO"
       ELSE
           DISPLAY "CLIENTE NAO LOCALIZADO"
       END-IF

Chuck Norris não compara flags com "S". A flag pergunta a ele qual valor deve assumir.



6. Inclusão: criar não significa jogar dados na primeira vaga

Na inclusão, o programa precisa proteger alguns estados.

Antes de tudo:

       IF WS-TOTAL-CLIENTES >= 50
           DISPLAY "LIMITE DE CLIENTES ATINGIDO"
       END-IF

Depois, deve receber os dados em uma área temporária:

       01  WS-CLIENTE-ENTRADA.
           05 WS-ENT-CODIGO         PIC 9(05).
           05 WS-ENT-NOME           PIC X(40).
           05 WS-ENT-CPF            PIC X(11).
           05 WS-ENT-TELEFONE       PIC X(15).

Por que não gravar diretamente na tabela?

Porque o usuário pode:

  • informar código duplicado;

  • deixar o nome vazio;

  • digitar CPF inválido;

  • cancelar a operação;

  • interromper a entrada no meio.

Se o programa escrever diretamente na tabela, poderá criar um registro parcialmente válido.

O fluxo correto é:

Receber → Validar → Verificar duplicidade → Gravar → Incrementar

Exemplo:

       2000-INCLUIR-CLIENTE.
           IF WS-TOTAL-CLIENTES >= 50
               DISPLAY "TABELA CHEIA"
           ELSE
               INITIALIZE WS-CLIENTE-ENTRADA
               PERFORM 2100-RECEBER-DADOS
               PERFORM 2200-VALIDAR-DADOS

               IF DADOS-VALIDOS
                   MOVE WS-ENT-CODIGO
                     TO WS-CODIGO-PESQUISA

                   PERFORM 7000-LOCALIZAR-CLIENTE

                   IF CLIENTE-ENCONTRADO
                       DISPLAY "CODIGO JA CADASTRADO"
                   ELSE
                       ADD 1 TO WS-TOTAL-CLIENTES

                       MOVE WS-CLIENTE-ENTRADA
                         TO WS-CLIENTE(WS-TOTAL-CLIENTES)

                       DISPLAY "CLIENTE INCLUIDO"
                   END-IF
               END-IF
           END-IF.

O contador deve ser incrementado somente quando o registro estiver aprovado para entrar na tabela.



7. A busca é o coração compartilhado

Consulta, alteração e exclusão começam da mesma forma:

Localize o cliente pelo código.

Em vez de escrever três pesquisas diferentes, o programa deve possuir uma rotina reutilizável:

       7000-LOCALIZAR-CLIENTE.
           SET CLIENTE-NAO-ENCONTRADO TO TRUE
           MOVE ZERO TO WS-POSICAO-ENCONTRADA

           PERFORM VARYING WS-POSICAO FROM 1 BY 1
               UNTIL WS-POSICAO > WS-TOTAL-CLIENTES
                  OR CLIENTE-ENCONTRADO

               IF WS-CODIGO(WS-POSICAO)
                    = WS-CODIGO-PESQUISA
                   SET CLIENTE-ENCONTRADO TO TRUE
                   MOVE WS-POSICAO
                     TO WS-POSICAO-ENCONTRADA
               END-IF
           END-PERFORM.

Essa é uma busca linear.

No pior caso, ela examina todos os registros:

O(n)O(n)

Para cinquenta clientes, isso é mais do que suficiente.

Um iniciante pode ficar tentado a implementar imediatamente uma pesquisa binária com SEARCH ALL. Mas ela exige que a tabela esteja ordenada pela chave.

Sem ordenação garantida, a pesquisa binária pode procurar o cliente com velocidade impressionante no lugar errado.

Dica de Chuck Norris:

Primeiro faça a busca correta. Depois meça. Só então otimize.



8. Consulta e listagem não são a mesma coisa

Ambas pertencem ao READ, mas possuem objetivos diferentes.

Consulta

Procura um cliente específico:

       3000-CONSULTAR-CLIENTE.
           DISPLAY "CODIGO: "
           ACCEPT WS-CODIGO-PESQUISA

           PERFORM 7000-LOCALIZAR-CLIENTE

           IF CLIENTE-ENCONTRADO
               PERFORM 7100-MOSTRAR-CLIENTE
           ELSE
               DISPLAY "CLIENTE NAO ENCONTRADO"
           END-IF.

Listagem

Percorre todos os registros ativos:

       4000-LISTAR-CLIENTES.
           IF WS-TOTAL-CLIENTES = ZERO
               DISPLAY "NENHUM CLIENTE CADASTRADO"
           ELSE
               PERFORM VARYING WS-POSICAO FROM 1 BY 1
                   UNTIL WS-POSICAO > WS-TOTAL-CLIENTES

                   DISPLAY "CODIGO: "
                       WS-CODIGO(WS-POSICAO)
                   DISPLAY "NOME: "
                       WS-NOME(WS-POSICAO)
               END-PERFORM
           END-IF.

A consulta é acesso seletivo. A listagem é varredura.

Essa diferença aparecerá novamente no Db2:

SELECT ... WHERE CODIGO = ?

para consulta individual, e um cursor para múltiplos registros.



9. O UPDATE entra pela porta principal

Agora chegamos à letra desaparecida.

O UPDATE não cria uma nova posição e não remove a existente. Ele altera determinados atributos do cliente na mesma ocorrência.

Antes:

CampoValor
Código00025
NomePaulo Henrique
CPF12345678909
Telefone11999990000

Depois:

CampoValor
Código00025
NomePaulo Henrique Silva
CPF12345678909
Telefone11988887777

Observe:

  • o cliente continua na mesma posição;

  • o código permanece igual;

  • o contador não muda;

  • não há deslocamento de registros;

  • apenas determinados campos são substituídos.

Portanto:

CREATE → WS-TOTAL-CLIENTES aumenta
UPDATE → WS-TOTAL-CLIENTES não muda
DELETE → WS-TOTAL-CLIENTES diminui

Se uma alteração incrementar o total, o programa terá criado uma duplicata em vez de atualizar o registro.



10. A chave não deve ser tratada como um telefone

O código identifica o cliente:

05 WS-CODIGO PIC 9(05).

Nome, CPF e telefone são atributos.

Em geral, o UPDATE deve preservar a chave.

Permitir que o operador altere livremente o código pode causar:

  • duplicidade;

  • perda de referências;

  • quebra da ordenação;

  • inconsistência com outros arquivos;

  • dificuldade de auditoria;

  • relações órfãs em bancos de dados.

No protótipo, ainda não existem contas, contratos ou endereços vinculados. Mesmo assim, proteger a chave ensina a mentalidade correta.

Se realmente fosse necessário trocar o código, essa deveria ser uma operação especial, com verificação de duplicidade e atualização das referências relacionadas.

Curiosidade: em VSAM KSDS, a chave primária não é tratada como um campo comum regravável. Muitas vezes, mudar a chave exige excluir o registro antigo e gravar outro com a nova chave.

Ou seja: até o VSAM olha desconfiado quando Igor diz “vou apenas dar um MOVE na chave”.



11. Antes e depois: o mini-COMMIT do laboratório

A melhor construção para o UPDATE utiliza duas imagens:

       01  WS-CLIENTE-ANTES.
           05 WS-ANTES-CODIGO       PIC 9(05).
           05 WS-ANTES-NOME         PIC X(40).
           05 WS-ANTES-CPF          PIC X(11).
           05 WS-ANTES-TELEFONE     PIC X(15).

       01  WS-CLIENTE-DEPOIS.
           05 WS-DEPOIS-CODIGO      PIC 9(05).
           05 WS-DEPOIS-NOME        PIC X(40).
           05 WS-DEPOIS-CPF         PIC X(11).
           05 WS-DEPOIS-TELEFONE    PIC X(15).

Depois de localizar o cliente:

       MOVE WS-CLIENTE(WS-POSICAO-ENCONTRADA)
         TO WS-CLIENTE-ANTES

       MOVE WS-CLIENTE(WS-POSICAO-ENCONTRADA)
         TO WS-CLIENTE-DEPOIS

Os novos dados são aplicados apenas na imagem DEPOIS.

O registro oficial continua intacto até:

  • os campos serem validados;

  • as duplicidades serem verificadas;

  • o usuário confirmar;

  • o programa decidir efetivar a operação.

Depois da confirmação:

       MOVE WS-CLIENTE-DEPOIS
         TO WS-CLIENTE(WS-POSICAO-ENCONTRADA)

Esse MOVE funciona como uma espécie de commit lógico didático.

Não é um COMMIT real de banco de dados, mas a analogia é útil:

Protótipo em memóriaSistema transacional
Imagem ANTESEstado confirmado
Imagem DEPOISAlteração preparada
ValidaçãoRegras e constraints
ConfirmaçãoAprovação
MOVE finalCommit lógico
Descartar DEPOISRollback lógico

Chuck Norris faz COMMIT olhando para o banco. O Db2 confirma por respeito.



12. Pressionar Enter significa o quê?

Suponha:

NOME ATUAL: PAULO HENRIQUE
NOVO NOME [ENTER=MANTER]:

O usuário apenas pressiona Enter.

Existem duas interpretações:

  1. apagar o nome;

  2. manter o nome atual.

O programa deve definir explicitamente a regra.

Em um cadastro, uma boa escolha é:

Campo vazio mantém o valor anterior.

Exemplo:

       DISPLAY "NOVO NOME [ENTER=MANTER]: "
       ACCEPT WS-NOVO-NOME

       IF WS-NOVO-NOME NOT = SPACES
           MOVE WS-NOVO-NOME
             TO WS-DEPOIS-NOME
       END-IF

O mesmo vale para CPF e telefone.

Mas surge outra pergunta: como o usuário apaga intencionalmente um campo opcional?

Uma solução seria aceitar um comando especial:

ENTER = manter
*     = limpar
valor = substituir

Exemplo:

       EVALUATE TRUE
           WHEN WS-NOVO-TELEFONE = SPACES
               CONTINUE
           WHEN WS-NOVO-TELEFONE = "*"
               MOVE SPACES TO WS-DEPOIS-TELEFONE
           WHEN OTHER
               MOVE WS-NOVO-TELEFONE
                 TO WS-DEPOIS-TELEFONE
       END-EVALUATE.

Esse pequeno detalhe mostra que interface não é apenas ACCEPT e DISPLAY. Ela também é um contrato de significado.



13. O CPF novo pode pertencer a outro cliente

Se o CPF puder ser alterado, o programa precisa verificar duplicidade.

Mas há uma armadilha.

Ao procurar o novo CPF, o sistema encontrará o CPF do próprio cliente. Por isso, a validação deve ignorar a posição que está sendo atualizada:

       MOVE "N" TO WS-CPF-DUPLICADO

       PERFORM VARYING WS-POSICAO FROM 1 BY 1
           UNTIL WS-POSICAO > WS-TOTAL-CLIENTES
              OR WS-CPF-DUPLICADO = "S"

           IF WS-POSICAO NOT = WS-POSICAO-ENCONTRADA
              AND WS-CPF(WS-POSICAO) = WS-DEPOIS-CPF
               MOVE "S" TO WS-CPF-DUPLICADO
           END-IF
       END-PERFORM.

A expressão:

WS-POSICAO NOT = WS-POSICAO-ENCONTRADA

é essencial.

Sem ela, o sistema rejeitaria o CPF atual como duplicado de si mesmo.

É o equivalente cadastral de Chuck Norris ser barrado na porta porque sua fotografia se parece demais com ele.



14. O fluxo completo da alteração

Uma estrutura modular poderia ser:

       5000-ALTERAR-CLIENTE.
           DISPLAY "=== ALTERAR CLIENTE ==="
           DISPLAY "CODIGO: "
           ACCEPT WS-CODIGO-PESQUISA

           PERFORM 7000-LOCALIZAR-CLIENTE

           IF CLIENTE-NAO-ENCONTRADO
               DISPLAY "CLIENTE NAO ENCONTRADO"
           ELSE
               PERFORM 5100-PREPARAR-IMAGENS
               PERFORM 5200-MOSTRAR-DADOS-ATUAIS
               PERFORM 5300-RECEBER-NOVOS-DADOS
               PERFORM 5400-VALIDAR-ALTERACAO

               IF DADOS-VALIDOS
                   PERFORM 5500-MOSTRAR-COMPARACAO
                   PERFORM 5600-CONFIRMAR-ALTERACAO

                   IF ALTERACAO-CONFIRMADA
                       PERFORM 5700-EFETIVAR-ALTERACAO
                   ELSE
                       DISPLAY "ALTERACAO CANCELADA"
                   END-IF
               END-IF
           END-IF.

Essa divisão deixa cada parágrafo com uma responsabilidade.

Preparação

       5100-PREPARAR-IMAGENS.
           MOVE WS-CLIENTE(WS-POSICAO-ENCONTRADA)
             TO WS-CLIENTE-ANTES

           MOVE WS-CLIENTE(WS-POSICAO-ENCONTRADA)
             TO WS-CLIENTE-DEPOIS.

Entrada

       5300-RECEBER-NOVOS-DADOS.
           INITIALIZE WS-NOVO-NOME
                      WS-NOVO-CPF
                      WS-NOVO-TELEFONE

           DISPLAY "NOVO NOME [ENTER=MANTER]: "
           ACCEPT WS-NOVO-NOME

           DISPLAY "NOVO CPF [ENTER=MANTER]: "
           ACCEPT WS-NOVO-CPF

           DISPLAY "NOVO TELEFONE [ENTER=MANTER]: "
           ACCEPT WS-NOVO-TELEFONE.

Efetivação

       5700-EFETIVAR-ALTERACAO.
           MOVE WS-CLIENTE-DEPOIS
             TO WS-CLIENTE(WS-POSICAO-ENCONTRADA)

           DISPLAY "CLIENTE ALTERADO COM SUCESSO".


15. E se nada tiver mudado?

O usuário pode entrar na alteração e manter todos os campos.

Nesse caso:

       IF WS-CLIENTE-ANTES = WS-CLIENTE-DEPOIS
           DISPLAY "NENHUMA ALTERACAO INFORMADA"
           SET DADOS-INVALIDOS TO TRUE
       END-IF.

Isso evita apresentar:

CLIENTE ALTERADO COM SUCESSO

quando nada foi alterado.

Em sistemas corporativos, atualizações vazias também podem gerar efeitos desnecessários:

  • logs;

  • auditoria;

  • locks;

  • escrita em disco;

  • replicação;

  • triggers;

  • mensagens;

  • alteração de timestamp;

  • eventos para outros sistemas.

Uma operação tecnicamente válida pode ainda ser operacionalmente inútil.


16. Exclusão: fechar o buraco deixado na mesa

Considere:

PosiçãoCliente
1Ana
2Bruno
3Carla
4Diego

Ao excluir Bruno, a posição 2 ficaria vazia.

Para manter a tabela compacta, os registros posteriores são deslocados:

       PERFORM VARYING WS-POSICAO
           FROM WS-POSICAO-ENCONTRADA BY 1
           UNTIL WS-POSICAO >= WS-TOTAL-CLIENTES

           MOVE WS-CLIENTE(WS-POSICAO + 1)
             TO WS-CLIENTE(WS-POSICAO)
       END-PERFORM

       INITIALIZE WS-CLIENTE(WS-TOTAL-CLIENTES)
       SUBTRACT 1 FROM WS-TOTAL-CLIENTES

Depois:

PosiçãoCliente
1Ana
2Carla
3Diego
4vazia

O INITIALIZE da última posição é importante. Sem ele, uma cópia residual de Diego poderia permanecer na área livre.

A aplicação talvez não a listasse porque o contador agora seria 3, mas o dado antigo continuaria fisicamente na memória.

Essa é uma curiosidade importante:

Um registro pode deixar de existir logicamente e continuar presente fisicamente.

O mesmo princípio aparece em discos, bancos, caches, filas e arquivos temporários. “Excluir” nem sempre significa destruir imediatamente todos os bytes.



17. Exclusão física ou lógica?

Em sistemas corporativos, o cliente raramente é simplesmente apagado.

Pode haver:

  • contratos;

  • contas;

  • movimentações;

  • obrigações regulatórias;

  • auditorias;

  • investigações;

  • histórico de atendimento.

Por isso, o sistema pode usar um status:

       05 WS-STATUS PIC X.
          88 CLIENTE-ATIVO    VALUE "A".
          88 CLIENTE-INATIVO  VALUE "I".
          88 CLIENTE-BLOQUEADO VALUE "B".

Então o DELETE de negócio seria:

       SET CLIENTE-INATIVO TO TRUE

O registro continua armazenado, mas deixa de participar das operações normais.

A isso damos frequentemente o nome de exclusão lógica.

O problema é que a aplicação precisa lembrar-se de filtrar os inativos. Caso contrário, Igor “exclui” o cliente no menu, mas ele aparece novamente na listagem cinco minutos depois como um fantasma do Db2.



18. ACCEPT e DISPLAY não são CICS por encantamento

O protótipo usa:

ACCEPT
DISPLAY

Isso oferece uma interface textual, mas não comprova que o sistema seja uma transação CICS nem uma verdadeira tela 3270.

Dependendo do ambiente:

  • ACCEPT pode ler da entrada padrão;

  • DISPLAY pode escrever na saída padrão;

  • em GnuCOBOL, pode ser um terminal Windows ou Linux;

  • em batch z/OS, a entrada pode vir de SYSIN;

  • a saída pode aparecer em SYSOUT;

  • em CICS, a interação normalmente envolve EXEC CICS e mapas BMS.

Uma execução batch poderia receber:

//SYSIN DD *
1
00001
PAULO HENRIQUE
12345678909
11999990000
0
/*

Isso não representa um operador navegando por uma tela 3270. É um job consumindo dados previamente fornecidos.

Em CICS, a construção seria diferente. A aplicação normalmente envia a tela, encerra a task e volta quando o usuário responde. Esse é o modelo pseudoconversacional.

A lição é simples:

COBOL é a linguagem. z/OS é o sistema operacional. CICS é o monitor transacional. 3270 é o modelo de terminal. Eles convivem, mas não são sinônimos.



19. Memória não é persistência

Todos os clientes do protótipo vivem na WORKING-STORAGE.

Quando o programa termina, os dados desaparecem.

Isso significa que o cadastro atual oferece:

  • manipulação de registros;

  • estado durante a execução;

  • regras de validação;

  • experiência didática.

Mas ainda não oferece:

  • persistência;

  • recuperação;

  • acesso simultâneo;

  • auditoria;

  • compartilhamento;

  • backup;

  • restart;

  • histórico.

A memória é como a prancheta do atendente.

VSAM ou Db2 são o arquivo oficial da empresa.

Chuck Norris memoriza todos os clientes. O restante da equipe precisa de persistência.



20. Primeiro degrau: arquivo sequencial

Uma próxima versão poderia utilizar um arquivo:

       SELECT CLIENTES-FILE
           ASSIGN TO CLIENTES
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS IS WS-FILE-STATUS.

E:

       FD CLIENTES-FILE.
       01 CLIENTES-RECORD.
          05 CLIENTE-CODIGO    PIC 9(05).
          05 CLIENTE-NOME      PIC X(40).
          05 CLIENTE-CPF       PIC X(11).
          05 CLIENTE-TELEFONE  PIC X(15).

Agora aparecem:

OPEN
READ
WRITE
CLOSE

E também:

FILE STATUS

O arquivo sequencial traz persistência, mas a atualização fica mais trabalhosa.

Para alterar um cliente:

  1. abrir o arquivo original;

  2. abrir um arquivo temporário;

  3. ler cada registro;

  4. gravar todos no temporário;

  5. quando encontrar o cliente, gravar a versão alterada;

  6. fechar os arquivos;

  7. substituir o original de maneira controlada.

É trabalhoso, mas ensina processamento batch real.



21. Segundo degrau: VSAM KSDS

Para acesso direto por código:

       SELECT CLIENTES-FILE
           ASSIGN TO CLIENTES
           ORGANIZATION IS INDEXED
           ACCESS MODE IS DYNAMIC
           RECORD KEY IS CLIENTE-CODIGO
           FILE STATUS IS WS-FILE-STATUS.

O CRUD passa a corresponder a:

OperaçãoVSAM
CriarWRITE
ConsultarREAD
AlterarREWRITE
ExcluirDELETE

Exemplo do UPDATE:

       READ CLIENTES-FILE
           KEY IS CLIENTE-CODIGO
       END-READ

       IF WS-FILE-STATUS = "00"
           MOVE WS-NOVO-NOME
             TO CLIENTE-NOME

           REWRITE CLIENTES-RECORD
           END-REWRITE

           IF WS-FILE-STATUS = "00"
               DISPLAY "CLIENTE ALTERADO"
           ELSE
               DISPLAY "ERRO NO REWRITE: "
                   WS-FILE-STATUS
           END-IF
       ELSE
           DISPLAY "CLIENTE NAO ENCONTRADO"
       END-IF.

Aqui, o FILE STATUS deixa de ser um detalhe e se torna parte da lógica.

Não basta executar REWRITE. É preciso perguntar ao sistema se ele conseguiu.



22. Terceiro degrau: Db2

No Db2:

UPDATE CLIENTE
   SET NOME     = :HV-NOME,
       CPF      = :HV-CPF,
       TELEFONE = :HV-TELEFONE
 WHERE CODIGO   = :HV-CODIGO

No COBOL:

       EXEC SQL
           UPDATE CLIENTE
              SET NOME     = :HV-NOME,
                  CPF      = :HV-CPF,
                  TELEFONE = :HV-TELEFONE
            WHERE CODIGO   = :HV-CODIGO
       END-EXEC.

Depois, o programa verifica SQLCODE:

       EVALUATE TRUE
           WHEN SQLCODE = ZERO
               EXEC SQL
                   COMMIT
               END-EXEC
               DISPLAY "CLIENTE ALTERADO"

           WHEN SQLCODE = 100
               DISPLAY "CLIENTE NAO ENCONTRADO"

           WHEN OTHER
               EXEC SQL
                   ROLLBACK
               END-EXEC
               DISPLAY "ERRO SQL: " SQLCODE
       END-EVALUATE.

Aqui aparece uma observação importante: dependendo do comando e da forma usada, “nenhuma linha atualizada” deve ser confirmado por diagnóstico apropriado, incluindo a quantidade de linhas afetadas. Não se deve imaginar que todo sucesso técnico corresponde a uma alteração de negócio.

O Db2 também introduz:

  • locks;

  • isolamento;

  • deadlock;

  • timeout;

  • integridade referencial;

  • constraints;

  • concorrência;

  • unidade de recuperação.

O protótipo pergunta:

Posso mudar este telefone?

O sistema corporativo pergunta:

Posso mudar este telefone, neste instante, sem violar regras, perder a atualização de outro usuário ou deixar metade da transação confirmada?



23. O problema dos dois operadores

Imagine dois usuários consultando o mesmo cliente:

Telefone atual: 11999990000

Operador A muda para:

11911112222

Operador B, que ainda vê a versão antiga, muda para:

11933334444

Se B gravar por último, a alteração de A poderá desaparecer.

Isso é chamado de lost update, ou atualização perdida.

A tabela em memória com um único usuário não mostra esse problema. Em um ambiente corporativo, ele precisa ser tratado por:

  • locks;

  • isolamento;

  • versionamento;

  • timestamp;

  • comparação da imagem anterior;

  • controle otimista de concorrência.

Uma estratégia seria atualizar somente se o registro ainda estiver na versão consultada:

UPDATE CLIENTE
   SET TELEFONE = :NOVO-TELEFONE,
       VERSAO   = VERSAO + 1
 WHERE CODIGO   = :CODIGO
   AND VERSAO   = :VERSAO-LIDA

Se nenhuma linha for atualizada, alguém modificou o registro antes.

Chuck Norris não sofre lost update. Quando ele altera uma linha, os outros usuários recebem um aviso antes mesmo de abrir a tela.



24. Passo a passo para construir o protótipo completo

Para um iniciante, eu seguiria esta ordem:

Passo 1 — Defina o registro

CODIGO
NOME
CPF
TELEFONE

Decida tamanhos e tipos conscientemente.

Passo 2 — Crie a tabela

OCCURS 50 TIMES

Mantenha um contador de registros ativos.

Passo 3 — Crie o menu

Use DISPLAY, ACCEPT e EVALUATE.

Passo 4 — Implemente a inclusão

Receba em área temporária, valide e somente depois grave.

Passo 5 — Centralize a pesquisa

Crie LOCALIZAR-CLIENTE e armazene a posição encontrada.

Passo 6 — Implemente consulta e listagem

Uma consulta por código e uma varredura completa.

Passo 7 — Implemente o UPDATE

Use imagens ANTES e DEPOIS, proteja a chave e peça confirmação.

Passo 8 — Implemente a exclusão

Localize, confirme, desloque os registros e diminua o contador.

Passo 9 — Trate limites e entradas inválidas

Teste tabela cheia, tabela vazia, código duplicado e cliente inexistente.

Passo 10 — Crie casos de teste

Não teste apenas o caminho feliz.



25. Roteiro de testes sob o olhar desconfiado de Chuck Norris

TesteResultado esperado
Incluir primeiro clienteTotal passa de 0 para 1
Incluir código repetidoInclusão recusada
Incluir 51º clienteLimite informado
Consultar cliente existenteDados exibidos
Consultar inexistenteMensagem controlada
Listar tabela vaziaNenhum cliente cadastrado
Alterar nomeMesma posição e mesmo código
Alterar CPF para CPF já usadoOperação recusada
Entrar no Update e não mudar nadaNenhuma alteração
Cancelar UpdateRegistro original preservado
Excluir primeiro clienteRegistros deslocados
Excluir cliente intermediárioTabela permanece compacta
Excluir último clienteÚltima posição inicializada
Cancelar exclusãoTotal e tabela permanecem iguais
Digitar opção inválidaMenu reapresentado
Encerrar e reabrirDados desaparecem na versão em memória

O último teste não é um defeito inesperado. É uma limitação conhecida da arquitetura.

Documentar limitações é uma forma de qualidade.





26. Easter eggs escondidos na WORKING-STORAGE

Easter egg 1 — O CRUD estava incompleto

O primeiro segredo estava no próprio acrônimo: faltava o U.

Easter egg 2 — Listar não cria outra letra

Consulta e listagem são duas formas de leitura. Portanto, ambas pertencem ao R.

Easter egg 3 — OCCURS 50 não significa cinquenta clientes

Significa espaço para cinquenta ocorrências. O contador informa quantas estão logicamente ocupadas.

Easter egg 4 — Excluir não apaga necessariamente os bytes

A exclusão lógica e os resíduos de memória mostram que existência física e existência de negócio são conceitos diferentes.

Easter egg 5 — O MOVE final imita um commit

As áreas ANTES e DEPOIS introduzem, em miniatura, o conceito de preparar, validar, confirmar ou abandonar uma mudança.

Easter egg 6 — O terminal pode não ser 3270

Uma tela verde não transforma automaticamente ACCEPT e DISPLAY em uma aplicação CICS.

Easter egg 7 — COBOL não significa necessariamente mainframe

COBOL pode rodar em outras plataformas. Para afirmar que é uma aplicação z/OS, é preciso demonstrar o ambiente, a compilação e a execução.

Easter egg 8 — O código mais importante pode ser o que não altera nada

A validação que impede uma operação indevida pode ser mais valiosa do que o MOVE que grava os dados.





Epílogo — O dia em que o UPDATE voltou ao menu

Ao final da revisão, o menu apareceu novamente:

1 - INCLUIR CLIENTE
2 - CONSULTAR CLIENTE
3 - LISTAR CLIENTES
4 - ALTERAR CLIENTE
5 - EXCLUIR CLIENTE
0 - SAIR

Chuck Norris examinou a WORKING-STORAGE.

Conferiu o limite de cinquenta posições.

Testou código duplicado.

Tentou atualizar um CPF já utilizado.

Pressionou Enter sem mudar nenhum campo.

Cancelou a alteração.

Excluiu o primeiro registro.

Depois encerrou o programa e confirmou que todos os clientes desapareceram, porque ainda estavam apenas na memória.

Igor respirou aliviado:

— Agora é um CRUD completo?

Chuck Norris respondeu:

— Agora ele possui as quatro operações. Completo é outra conversa.

E essa talvez seja a maior lição do projeto.

Um CRUD em memória pode ser excelente para aprender:

  • estruturação de dados;

  • lógica procedural;

  • modularização;

  • pesquisa;

  • validação;

  • estados;

  • inclusão;

  • consulta;

  • alteração;

  • exclusão.

Mas um sistema corporativo também exige:

  • persistência;

  • controle de concorrência;

  • segurança;

  • auditoria;

  • recuperação;

  • integridade;

  • testes;

  • tratamento de erros;

  • observabilidade;

  • operações transacionais.

O protótipo não precisa fingir que já é tudo isso.

Seu valor está justamente em mostrar uma evolução compreensível:

OCCURS em memória
        ↓
arquivo sequencial
        ↓
VSAM KSDS
        ↓
Db2
        ↓
CICS
        ↓
segurança, auditoria e produção

O jovem padawan que entende essa sequência deixa de ser alguém que apenas conhece comandos COBOL.

Ele começa a compreender como dados nascem, mudam, sobrevivem, desaparecem e precisam ser protegidos dentro de sistemas que não podem improvisar.

E, sob o olhar desconfiado de Chuck Norris, a regra final ficou registrada:

Um UPDATE não é apenas sobrescrever caracteres. É localizar a entidade correta, preservar sua identidade, preparar uma nova versão, validar as regras, impedir conflitos e somente então alterar o estado oficial.

Igor tentou acrescentar essa frase ao programa usando um DISPLAY.

Chuck Norris pediu que ele criasse primeiro o FILE STATUS.



Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...