Pular para o conteúdo
Sistemas

Transactional outbox: como evitar eventos perdidos entre sistemas

Entenda escrita dupla, publicação de eventos, idempotência e reconciliação em integrações financeiras e operacionais.

Transactional outbox: como evitar eventos perdidos entre sistemas

O pedido foi salvo, mas o financeiro nunca recebeu a notificação. A equipe vê a venda na tela e acredita que a cobrança está em andamento. Na prática, uma falha entre duas operações criou um estado que ninguém percebeu imediatamente.

Transactional outbox é um padrão para registrar a mudança de negócio e a intenção de publicar um evento na mesma transação de banco. Um processo separado envia os eventos pendentes. A solução reduz um tipo de inconsistência, mas ainda exige consumidores preparados para repetição e reconciliação.

O problema da escrita dupla

Salvar um pedido e enviar uma mensagem para outro sistema são duas ações distintas. Se a primeira funciona e a segunda falha, os sistemas divergem. Inverter a ordem apenas muda o risco: a notificação pode sair antes de a gravação ser confirmada.

A orientação da AWS sobre transactional outbox apresenta esse problema e destaca cuidados como mensagens duplicadas e ordem de publicação. O padrão não significa que todos os sistemas participem de uma única transação distribuída. Ele organiza o compromisso entre o banco local e a publicação posterior.

Um fluxo simples para entender o desenho

Em um exemplo hipotético, aprovar um contrato grava o novo estado e uma linha na tabela de eventos de saída. Se a transação for desfeita, nenhuma das duas gravações é confirmada. Se for concluída, o evento fica disponível para um publicador.

O publicador seleciona eventos pendentes, envia ao destino e registra o resultado. Quando o destino está indisponível, o registro permanece tratável. O contrato não precisa desaparecer nem ser aprovado novamente para tentar a integração.

Aprovação do contrato
        |
        v
Transação: contrato + evento de saída
        |
        v
Publicador -> destino -> confirmação
        |
        v
Histórico de tentativas e reconciliação

Por que ainda pode haver duplicidade

O destino pode receber a mensagem e a confirmação se perder. O publicador, sem saber que houve sucesso, tenta novamente. Por isso, o consumidor precisa reconhecer o mesmo evento e evitar repetir o efeito de negócio.

Um identificador estável permite associar as tentativas à mesma ocorrência. Não gere uma nova identidade a cada repetição. Para uma cobrança, o importante é que o evento aprovado uma vez não gere dois débitos porque a rede respondeu de forma ambígua.

QuestãoDecisão necessáriaEvidência de teste
IdentidadeComo reconhecer a mesma ocorrência?Repetição não cria novo efeito
OrdemQuais eventos dependem uns dos outros?Cancelamento não é perdido
RetentativaQuando repetir e quando interromper?Falha permanente não entra em loop
ConcorrênciaQuem reserva cada evento para envio?Dois workers não executam sem controle
ReconciliaçãoComo encontrar divergências?Registro local comparável ao destino

Evite uma fila invisível dentro do banco

Uma tabela outbox sem monitoramento pode apenas trocar um problema silencioso por outro. Acompanhe a idade do evento mais antigo, o volume pendente, tentativas e motivos de falha. O indicador relevante não é somente quantas linhas existem, mas há quanto tempo o compromisso de negócio está esperando.

Defina retenção e arquivamento. Guardar todo evento para sempre na tabela operacional pode aumentar custo e dificultar consultas. Remover cedo demais pode prejudicar investigação. A política deve preservar rastreabilidade suficiente sem transformar o mecanismo de entrega em um repositório sem gestão.

Quando o padrão faz sentido

O padrão é útil quando uma alteração local precisa provocar efeitos externos com possibilidade de repetição e recuperação. Não é obrigatório para toda ação de interface. Uma consulta simples ou uma tarefa sem compromisso persistente pode ser resolvida com menos componentes.

Também não resolve sozinho um processo que envolve várias compensações de negócio. Cancelar uma venda, estornar um pagamento e liberar estoque pode exigir um desenho mais amplo. A outbox pode ser uma peça, mas a empresa ainda precisa definir o que fazer quando uma etapa falha depois de outra já ter sido concluída.

Teste falhas nos pontos certos

O teste mais revelador interrompe o fluxo depois de o destino aceitar a mensagem e antes de o publicador registrar a confirmação. Depois, execute novamente. O resultado esperado é recuperação sem duplicar o efeito.

Inclua falha de autenticação, mensagem inválida, destino lento e processamento concorrente. Cada situação pede uma resposta diferente. Repetir uma mensagem inválida indefinidamente não a torna válida; exige correção e revisão antes de reprocessar.

Checklist de projeto

  • Evento gravado junto da mudança local.
  • Identificador estável preservado em todas as tentativas.
  • Consumidor idempotente para o efeito relevante.
  • Reserva de trabalho e concorrência definidas.
  • Alertas por atraso e falhas persistentes.
  • Rotina de reconciliação e reprocessamento controlado.
  • Política de retenção documentada.

Perguntas frequentes

Isso garante processamento exatamente uma vez?

Não por si só. O desenho precisa considerar repetição de entrega, confirmação perdida e idempotência do consumidor. A garantia depende do fluxo completo.

Posso usar a outbox sem microsserviços?

Sim. Um sistema único que integra serviços externos também pode enfrentar escrita dupla. O problema existe independentemente do rótulo arquitetural.

A interface deve esperar a integração terminar?

Depende da regra. Se houver processamento assíncrono, o usuário precisa enxergar o estado real, como aprovado e aguardando sincronização, sem receber uma confirmação falsa.

Referência e aplicação

Veja o padrão transactional outbox na AWS. O exemplo comercial e o roteiro de testes acima são ilustrações próprias.

Para integrações financeiras, complemente com o guia de cobrança recorrente e avalie a integração de sistemas da A2CR.

Compartilhar