18 de Setembro de 2025
Transação e fechamento de fronteira: o que fica dentro e o que deve sair
Transação não existe para abraçar tudo que acontece no fluxo; ela existe para fechar uma fronteira de consistência com critério.
Andrews Ribeiro
Founder & Engineer
3 min Intermediario Sistemas
O problema
Muita discussão sobre transação vira uma mistura perigosa de intenções.
O time quer:
- gravar no banco
- publicar evento
- chamar gateway externo
- enviar email
- atualizar cache
e gostaria de pensar nisso tudo como uma operação única.
O problema é que o sistema real não funciona assim.
Banco até pode participar de uma transação local.
Provider externo, fila, webhook e email não entram magicamente nessa mesma garantia.
Modelo mental
Transação é uma fronteira de consistência local.
Ela responde:
quais mudanças precisam sair juntas do ponto de vista deste armazenamento?
Essa é uma pergunta mais útil do que:
como eu faço tudo acontecer sem risco nenhum?
Porque a segunda costuma empurrar o time para promessas irreais.
O que normalmente fica dentro
Dentro da transação costumam fazer sentido coisas como:
- criar ou atualizar registros que precisam nascer coerentes entre si
- reservar estado local
- registrar fato interno que depende do mesmo commit
- persistir um outbox na mesma unidade local
Exemplo:
- criar pedido
- gravar itens
- marcar estoque reservado
- persistir evento no outbox
Tudo isso ainda é estado do seu lado.
Faz sentido fechar junto.
O que normalmente deve sair
Fora da transação costumam ficar:
- chamada HTTP para outro sistema
- envio de email
- publicação em broker fora do mesmo commit local
- recálculo pesado
- atualização de cache compartilhado
Não porque essas coisas são menos importantes.
Mas porque elas não obedecem à mesma mecânica de commit do banco.
Quando você tenta tratá-las como se obedecessem, começa a vender consistência que não existe.
Exemplo simples
Imagine “confirmar pagamento do pedido”.
Uma fronteira razoável pode ser:
- gravar pagamento aprovado
- mudar pedido para
paid - registrar evento
order_paidno outbox
Isso fecha um estado interno consistente.
Depois do commit:
- worker publica o evento
- email sai
- ERP é avisado
Se o email falhar, o pedido continua pago.
Se o ERP atrasar, o sistema ainda sabe o que já foi confirmado.
Isso é muito mais honesto do que tentar empacotar tudo na mesma ilusão de atomicidade.
O erro comum
O erro comum é segurar a transação enquanto espera coisa demais:
- chamada externa
- cálculo pesado
- retry improvisado
- lógica de compensação mal definida
O resultado costuma ser:
- lock por tempo demais
- throughput pior
- timeout
- estado difícil de entender
Transação longa raramente deixa o sistema “mais seguro”.
Frequentemente deixa o sistema mais frágil.
Outbox entra justamente aqui
Outbox ajuda porque separa duas coisas:
- confirmar o estado local
- propagar esse fato para fora
Isso evita o clássico problema de:
- commit no banco deu certo
- publicação do evento falhou
Você não resolve tudo.
Mas pelo menos torna a fronteira explícita e reprocessável.
Como um senior pensa
Quem tem mais experiência normalmente pergunta:
- o que realmente precisa sair consistente neste commit?
- o que pode reagir depois?
- o que é local e o que já é integração?
- se der falha no meio, consigo explicar o estado final sem inventar desculpa?
Essa pergunta é melhor do que abrir a conversa com:
“vamos colocar tudo dentro de uma transação”
Ângulo de entrevista
Esse tema aparece muito em system design, backend e debugging de produção.
O entrevistador quer perceber se você sabe:
- separar consistência local de side effect externo
- evitar transação longa demais
- pensar em outbox, retry e reprocessamento com clareza
- explicar o que é garantido e o que é eventual
Resposta forte parece algo como:
“Eu fecharia em transação só o estado interno que precisa sair coerente no banco. O que depende de sistema externo eu trataria como efeito posterior, idealmente com outbox e reprocessamento, para não fingir atomicidade que eu não controlo.”
Isso mostra julgamento.
Takeaway direto
Transação boa não é a que tenta proteger o mundo inteiro.
É a que fecha bem a fronteira que realmente está sob seu controle.
Resumo rápido
O que vale manter na cabeça
- Transação serve para fechar consistência local, não para fingir atomicidade global.
- Banco e efeitos externos quase nunca deveriam ficar misturados na mesma promessa mental de tudo-ou-nada.
- Quanto mais longa a transação, maior o custo de contenção, lock e imprevisibilidade.
- Uma fronteira boa deixa claro o que é confirmado agora e o que acontece depois.
Checklist de pratica
Use isto ao responder
- Consigo dizer exatamente qual estado precisa sair consistente no commit?
- Tenho algum side effect externo acontecendo dentro de transação sem necessidade?
- Se uma integração externa falhar, o sistema sabe o que já foi confirmado localmente?
- Consigo explicar a fronteira transacional sem usar 'atômico' para tudo?
Você concluiu este artigo
Compartilhar esta página
Copie o link manualmente no campo abaixo.