2PC

Saga vs 2PC: 5 motivos por que sua arquitetura de microserviços cria dados órfãos

Por Flank Manoel da Silva Especialista Sênior Full Stack | Analista de Infraestrutura e Performance

Se você trabalha com Sagas, 2PC e eventos, tem algo que ninguém te conta com a devida honestidade: o problema não é só manter tudo “consistente”, é descobrir, tarde demais, que parte dos seus dados virou um cemitério silencioso.

E esse cemitério custa caro em estorno manual, chargeback, auditoria, risco regulatório e erosão de confiança do usuário.

O que sua stack distribuída não está te contando

Em linguagem de chão de fábrica:

  1. Você aprova um pagamento.
  2. O estoque falha.
  3. A Saga “promete” compensar.
  4. O barramento de eventos engasga bem na hora da compensação.
  5. O sistema diz pro usuário: “falhou, seu pedido não foi criado”.
  6. O cartão mostra: transação autorizada.

Isso acontece hoje em muita arquitetura de microserviços rodando em e‑commerce americano médio.

O que você precisa entender agora:

  • Sagas não eliminam o risco de inconsistência, elas deslocam o risco para o barramento de eventos e para a disciplina de compensação.
  • 2PC reduz esse tipo de dado órfão, mas cobra o preço em latência, bloqueio e fragilidade em ambientes distribuídos com alta disponibilidade.
  • Se você não mede “taxa de sucesso das compensações sob falha de infraestrutura”, sua arquitetura de microserviços está voando no escuro.
  • O custo real não é técnico: é operacional e financeiro — gente em backoffice reconciliando, estornando, ligando para cliente irritado e explicando “foi um problema sistêmico”.

Veredito rápido: se você não tem um painel explícito de “transações em limbo”, sua arquitetura de microserviços já está acumulando dados órfãos em produção.

Como eu quebrei um fluxo de pagamento distribuído

Eu não cheguei a essa conclusão lendo blogpost de vendor. Cheguei quebrando um fluxo de pagamento real de um cliente mid-market nos EUA, com pico de Black Friday.

Cenário simplificado:

  • Frontend Next.js
  • Backend em arquitetura de microserviços rodando em Kubernetes
  • Event bus em Kafka
  • Orquestração de Saga para checkout:
    1. Reservar estoque
    2. Autorizar pagamento (Stripe)
    3. Criar pedido
    4. Enviar e‑mail/notify

Nos testes de carga “normais”, tudo lindo. O problema aparece quando eu começo a fazer o que time de QA raramente faz: simular falha específica no terceiro passo da Saga, sob rede degradada.

O experimento crítico

Eu forcei o cenário:

  • Aprovação de pagamento OK (Stripe responde 200/authorized).
  • Mensagem de “criar pedido” publicada no tópico.
  • Caos controlado:
    • Latência variável no Kafka.
    • Drops intermitentes de pacote em um dos brokers.
    • Crash proposital do consumer responsável pela compensação.

O que eu medi:

  • Percentual de transações onde: Pagamento aprovado; Pedido não criado; Compensação (estorno) não executada automaticamente.
  • Tempo médio até o primeiro indício humano de que algo estava errado (reclamação no suporte, chargeback, alerta de conciliação).

Resultado? Na primeira rodada: Cerca de 0,3% das transações iam para o limbo. Em volume de Black Friday, 0,3% era dinheiro e reputação suficientes para virar incidente de diretoria. E tudo isso em uma arquitetura de microserviços “padrão de mercado”, com Sagas, DLQ e dashboards “bonitos”.

Onde a engenharia normalmente se engana

O time tinha confiança cega em três pilares:

  1. “Usamos padrão Saga, então temos consistência eventual resolvida.”
  2. “Kafka é resiliente, se falhar, reprocessa a mensagem.”
  3. “Temos DLQ, então nada se perde.”

Na prática:

  • A mensagem de compensação às vezes nem era produzida.
  • Em outros casos, era produzida porém nunca consumida, por configuração de consumer group bugada sob autoscaling.
  • Em alguns fluxos, a compensação dependia de serviço que também estava degradado.

Moral: a arquitetura de microserviços empacotou a complexidade num lugar menos visível, o barramento de eventos, e o time assumiu que “a biblioteca cuida”.

Por que isso virou uma urgência para empresas dos EUA agora

Três forças estão convergindo:

Escala e burst imprevisível

Mesmo um e‑commerce mid-market hospedado em Shopify Plus + stack própria em AWS pode explodir de tráfego por causa de: Influencer grande no TikTok; Promoção relâmpago; Afiliado com mailing agressivo. A arquitetura de microserviços precisa aguentar burst e, sob burst, Sagas tendem a sofrer mais em termos de visibilidade e controle de compensações.

Regulação e litígio

Nos EUA, um padrão recorrente de: Cobrança sem entrega; Estorno demorado ou ausente; é combustível para: Reclamações no CFPB; Class actions; Investigação de práticas desleais. A arquitetura de microserviços que gera dados órfãos em pagamentos mexe com risco jurídico, não só técnico.

Pressão por time-to-market

Times estão quebrando monolitos legados a todo custo: “Vamos migrar para arquitetura de microserviços com Sagas em seis meses.” Esse tipo de migração, sob pressão, corta o que é “invisível ao usuário”: monitoria de compensação, trilhas de auditoria, reconciliation jobs robustos.

Contexto duro: hoje, em boa parte das empresas digitais americanas, a escolha Saga vs 2PC é tomada mais pela moda arquitetural do que por uma análise fria dos riscos de dados órfãos.

Como a escolha de arquitetura muda o risco conforme o tipo de empresa

Vou quebrar em três perfis típicos que vejo nos EUA e mostrar como Saga vs 2PC e arquitetura de microserviços se comportam na prática.

1. E‑commerce que vive de promoções agressivas

Stack típica: Frontend React/Next.js; Backend em arquitetura de microserviços Node/Java/Python; Kafka ou RabbitMQ; Payment gateway (Stripe, Adyen, PayPal); Warehouse integrado via API.

Picos de tráfego destroem qualquer suposição de ordem “perfeita” de eventos. Sagas coreografadas (cada serviço reage a eventos) tornam debugging um inferno. Se o fluxo de compensação não for prioritário no design, o número de ordens “zumbi” cresce proporcionalmente ao tráfego. Aqui, Sagas são quase inevitáveis, porque: 2PC distribuído, envolvendo sistema de estoque, pagamento e ERP, é impraticável em termos de latência e acoplamento. Mas a arquitetura de microserviços precisa ser pensada com trilhas de auditoria como feature de primeira classe.

2. Fintech de crédito e meios de pagamento

Stack comum: Core bancário legado com 2PC interno robusto; Camada de arquitetura de microserviços por cima para APIs públicas, onboarding, scoring; Event bus (Kafka, Pulsar) para streaming de eventos financeiros.

Aqui o problema muda de lugar: O core é rigidamente consistente (2PC, locking, etc.). A camada externa em arquitetura de microserviços tenta ser “ágil” com eventos e Sagas. Cenário típico: O core confirma uma transação (strong consistency). A arquitetura de microserviços externa falha em publicar ou processar evento de confirmação. Sistemas satélites (fraude, CRM, relatórios, notificações) não enxergam a transação. Resultado prático: Cliente vê no app uma coisa, no extrato outra. Time de suporte liga para o backoffice, que consulta o core manualmente. “Gasto oculto” com reconciliação humana diária. 2PC resolve boa parte da consistência de dinheiro “de verdade”. Mas a arquitetura de microserviços que orbita o core volta a gerar dados órfãos em escala.

3. SaaS B2B com workflow complexo (billing, invoices, usage-based)

Stack: Arquitetura de microserviços multi-tenant; Event-driven para tudo: criação de usuário, billing, quotas, métricas; Integração forte com Stripe/Braintree.

Pressão típica: Altas exigências de relatórios financeiros precisos (revenue recognition, IFRS/GAAP). Múltiplas moedas, múltiplos meios de cobrança. Aqui o problema dos dados órfãos costuma aparecer em: faturas criadas sem o devido evento de pagamento; pagamento processado sem fatura sincronizada; regras de desconto aplicadas de forma divergente entre serviços. O que diferencia quem sobrevive: Não é só “usar Saga direito”. É ter um desenho de arquitetura de microserviços que coloca reconciliação e auditoria no centro, não como job opcional.

Tabela comparativa de risco prático

SegmentoDependência de SagasTolerância a inconsistência temporáriaCusto de dados órfãos
E‑commerce promoçõesAltaAltaAlto
Fintech de créditoMédiaBaixíssimaMuito Alto
SaaS B2B billingAltaMédiaAlto

Resumo:

  • E‑commerce: alta dependência de Sagas, alta tolerância momentânea, mas alto custo reputacional em massa.
  • Fintech: mistura 2PC no core com arquitetura de microserviços externa, tolerância baixíssima a inconsistência monetária, custo jurídico alto.
  • SaaS B2B: dependência alta de eventos, tolerância média a inconsistência temporária, mas custo alto em contabilidade e confiança de clientes enterprise.

O que ninguém te conta sobre Sagas e 2PC

1. Sagas são ótimas em slides, cruéis em auditoria

Sagas são vendidas como: Modelo natural para arquitetura de microserviços; Fácil de escalar; Independente de transações distribuídas “bloqueantes”.

O que quase ninguém reforça: Cada ação compensatória precisa ser tão auditável quanto a ação original. Na prática, não é. Logs de compensação, em muitas empresas, não entram no mesmo pipeline de observabilidade. Ferramentas de tracing (Jaeger, Zipkin) são configuradas para o “happy path”, não para a cadeia de rollback. Na minha experiência, isso faz com que: Durante incidente, engenheiros olhem apenas para o fluxo principal. O “cemitério de dados” esteja escondido em DLQs, topicos de retry e tabelas temporárias jamais reconciliadas.

2. 2PC não é vilão absoluto, ele é só caro no lugar errado

2PC virou quase palavrão em discussões de arquitetura de microserviços: “É lento”; “Bloqueia recursos”; “Não escala”.

Aceitar um pequeno cluster transacional com 2PC em um núcleo de verdade pode ser mais honesto do que tentar resolver tudo com Sagas. Muitas vezes, tenta-se substituir essa consistência por travas distribuídas, mas como já analisei em 5 Falhas do Distributed Lock e a Integridade de Dados, essa abordagem possui gargalos que podem comprometer a integridade do dado tanto quanto uma Saga mal desenhada.

3. O barramento de eventos vira ponto único de falha moral

Tecnicamente, o Kafka não é um ponto único de falha. Mas, em termos de “moral arquitetural”, ele acaba se tornando um. Porque: Você transfere para ele toda a esperança de não perder eventos. Costuma-se subestimar: Falhas de produtores; Configurações de retenção; Erros de evolução de esquema; Comportamento sob rebalanceamento de partições. Quando o marketing te fala: “basta ter um barramento confiável e Sagas bem definidas”, ele omite o custo real de operar um barramento em linha com o rigor financeiro de um banco.

Como eu reestruturei a arquitetura para reduzir dados órfãos (sem matar o negócio)

Agora entra a parte que interessa: o protocolo de ação. Vou descrever como, em um ambiente real, ajustei uma arquitetura de microserviços baseada em Sagas para: diminuir drasticamente transações em limbo; melhorar a visibilidade de auditoria; sem voltar para o monolito ou para 2PC generalizado.

Passo 1 – Definir “verdades locais” e “verdades globais”

Primeiro, mapeei quais sistemas: Podiam aceitar inconsistência temporária; Não podiam, de jeito nenhum. Por exemplo: Verdade global: dinheiro movimentado (autorização, captura, estorno); estoque físico reservado. Verdade local: e-mail transacional; notificação push; CRM tag. Isso permitiu: Desenhar um pequeno “núcleo duro” com garantias mais fortes; Manter o resto da arquitetura de microserviços mais relaxado.

Passo 2 – Traçar a “linha vermelha” da transação

Para cada fluxo crítico (ex: checkout), definimos: Qual é o ponto máximo até onde aceitamos Sagas puras; Em que ponto precisamos de algo mais garantido: Outbox Pattern rígido na fronteira com o banco; Execução quase transacional dentro do escopo de um único banco relacional. Essa “linha vermelha” ficou documentada visualmente.

Passo 3 – Medir “taxa de compensação bem-sucedida” sob falha proposital

Aqui volta a auditoria de transações longas. Em vez de só olhar 99,9% de sucesso no happy path, instrumentei:

  • Métrica 1: ratio de compensações executadas vs compensações esperadas.
  • Métrica 2: tempo médio até a compensação.
  • Métrica 3: quantidade de transações que precisaram de intervenção humana.

Como fizemos: Testes de chaos engineering focados em: Derrubar o service responsável pela compensação; Degradar rede entre producers e Kafka; Introduzir falhas aleatórias na gravação em banco. O que isso expôs: Gaps de idempotência em vários handlers; Sequência de passos sensíveis à ordem de arrival dos eventos; Pontos da arquitetura de microserviços onde a compensação vivia em serviço pouco monitorado.

Passo 4 – Criar um “painel de transações em limbo”

Sem interface bonita, nada funciona. Criei um painel operacional cujo foco era assustar quem toma decisão: Lista de: Pagamentos aprovados sem pedido; Reservas de estoque sem liberação; Estornos iniciados sem confirmação do gateway. KPIs: Total de valor “em disputa”; Tempo médio em limbo. Esse painel virou: Ferramenta de gestão diária para operações; Termômetro de qualidade da arquitetura de microserviços.

Passo 5 – Rebaixar complexidade onde 2PC fazia sentido

Em dois pontos críticos, eu deliberadamente reintroduzi algo próximo de 2PC, mas com escopo pequeno: Entre ledger interno e tabela de autorização de pagamentos; Entre reserva de estoque física e registro de pedido em estado “confirmado”. Isso não virou um 2PC distribuído entre todos os serviços. Virou um pequeno “cluster transacional” dentro da arquitetura de microserviços, limitado a dois bancos em ambiente fortemente controlado. Resultado: Latência de alguns fluxos aumentou milissegundos. Mas praticamente zeramos um tipo específico de dado órfão relacionado a reserva de estoque duplicada.

Passo 6 – Reconciliação como produto, não como job de madrugada

Por fim, tratei reconciliação como feature: APIs dedicadas para: varrer DLQs; inspeções de consistência entre sistemas internos e gateway de pagamentos. Tarefas programadas com: dashboards próprios; SLAs de atendimento (por exemplo: “toda transação em limbo por mais de 15 minutos dispara alerta de nível X”). Isso colocou a reconciliação no coração da arquitetura de microserviços, em vez de deixá-la como script escondido que só um engenheiro conhece.

Efeito prático: como isso muda a vida de cada tipo de negócio

E‑commerce agressivo

Depois de ajustar a arquitetura de microserviços e o protocolo: Black Friday rodou com aumento de 3x no tráfego. Incidentes de “cobrado e não recebeu” caíram para quase zero. Quando ocorriam, eram detectados pelo painel em minutos, não por ticket do cliente em horas. Financeiramente: Menos chargebacks; Menos tempo de time de suporte lidando com exceção; Mais confiança em campanhas de alto risco.

Fintech de pagamentos

Ao reforçar a fronteira entre core transacional (mais próximo de 2PC) e arquitetura de microserviços externa, o ganho foi: Menos divergência entre visão do app e visão do ledger; Redução do tempo de conciliação contábil no fechamento de mês; Melhora substancial da postura de compliance diante de auditorias.

SaaS B2B

Para o SaaS centrado em billing: Adoção de métricas de transações em limbo reduziu divergências de faturamento detectadas pelos próprios clientes. Fechamento contábil ganhou previsibilidade. A arquitetura de microserviços permaneceu modular, mas o domínio financeiro ganhou mais “gravidade” e coerência.

Quando insistir em Saga, quando aceitar 2PC e quando misturar

Depois de anos batendo cabeça, a regra prática que uso hoje é:

Use Saga pura quando:

  • O domínio tolera inconsistência temporária.
  • O custo por incidente é baixo e o volume de eventos é muito alto.
  • A rastreabilidade e auditoria estão bem endereçadas na arquitetura de microserviços.

Aceite um núcleo 2PC quando:

  • O domínio é financeiro ou de inventário físico crítico.
  • Os sistemas envolvidos são poucos e bem controlados.
  • A falha de consistência tem impacto regulatório ou jurídico.

Misture quando:

  • Parte do domínio é crítica, parte é periférica.
  • Você quer extrair o melhor de cada abordagem: 2PC/consistência forte no “miolo”; Sagas e eventos na borda para integração com resto da arquitetura de microserviços.

A pior escolha, ironicamente, é: Tentar resolver tudo com Saga porque “é o padrão em microserviços”; Colocar tudo em uma única arquitetura de microserviços orquestrada sem delimitar bem núcleos de verdade e fronteiras contratuais.

Conclusão

A transição para uma arquitetura de microserviços é frequentemente vendida como a libertação do monolito, mas sem o devido rigor transacional, ela pode se tornar uma prisão de inconsistências. O “caos da consistência eventual” não é uma falha da tecnologia em si, mas da expectativa irreal de que o sistema se recuperará sozinho sem uma rede de segurança projetada manualmente.

Sagas e eventos são ferramentas poderosas para escala, mas são péssimas para quem precisa de respostas binárias e imediatas sobre “onde está o dinheiro”. Se sua arquitetura ignora o cemitério de dados órfãos, você não está apenas acumulando dívida técnica; você está acumulando um passivo financeiro e operacional que, em algum momento, cobrará o seu preço.

O protocolo de saída para líderes técnicos:

  1. Audite o Limbo: Se você não tem um painel que mostre transações que “começaram mas nunca terminaram”, sua prioridade de amanhã deve ser criá-lo.
  2. Abandone o Dogmatismo: Não tenha medo de usar consistência forte (ou pequenos núcleos de 2PC) onde o dado é sagrado. Microserviços não precisam ser 100% event-driven para serem eficientes.
  3. Cultura de Reconciliação: Trate a conferência de dados como uma funcionalidade vital do produto, e não como um script de emergência.

No fim das contas, a melhor arquitetura de microserviços não é a que tem o diagrama mais elegante no PowerPoint, mas a que permite que você durma tranquilo sabendo que, se o sistema falhar, ele saberá exatamente como (e onde) se reconstruir.