Confirmar uma alteração no banco e avisar outros sistemas são duas operações diferentes. A outbox registra o aviso junto da alteração para que a publicação possa continuar depois de uma falha, com acompanhamento explícito do que ainda está pendente.
Encontre a lacuna entre confirmar e avisar
Imagine a empresa fictícia Técnica Aurora, que encerra ordens de manutenção em um sistema próprio. Quando um técnico conclui o serviço, o banco registra o encerramento e a aplicação envia um evento para preparar o relatório do cliente. Em uma interrupção de rede, o encerramento fica salvo, mas o aviso não chega. A equipe vê a ordem concluída e presume que o relatório está a caminho. Esse é um problema de responsabilidade entre etapas: o registro principal está correto, porém não existe uma pendência durável dizendo que ainda falta publicar a mudança.
Inverter as operações não resolve. Se o evento for enviado antes de confirmar a transação, o gerador de relatórios poderá agir sobre uma conclusão que depois falhou. Também não basta colocar ambas as chamadas no mesmo bloco de tratamento de erro da linguagem. Uma transação local do banco não inclui automaticamente o sistema externo. O primeiro exercício é desenhar as fronteiras de confirmação e perguntar o que permanece registrado quando o processo termina abruptamente entre cada par de passos.
A orientação da AWS sobre outbox transacional apresenta o registro da mudança e do evento na mesma transação, com publicação posterior por outro processo. A documentação também destaca repetição e ordem de mensagens como preocupações. Este tutorial aplica essas ideias a uma rotina de manutenção; o desenho de estados, retenção e testes abaixo precisa ser ajustado aos contratos concretos da empresa.
Escreva o fato de negócio e a intenção de publicação juntos
Defina primeiro o fato que o evento comunica. “Ordem de serviço concluída” deve significar que os critérios de conclusão foram atendidos e persistidos. Não use o mesmo nome para um clique no botão, uma tentativa e uma confirmação. Na empresa fictícia, o fato inclui identificação da ordem, versão da ordem após o encerramento e horário da conclusão. Se há uma aprovação técnica posterior, a conclusão operacional e a aprovação precisam ter nomes diferentes, porque seus consumidores podem tomar decisões distintas.
Na transação que grava a conclusão, acrescente uma linha na outbox com identificador próprio de evento, tipo, versão do contrato, chave do objeto e conteúdo necessário. A transação confirma as duas gravações ou nenhuma. O identificador do evento é estável durante toda a publicação e não deve ser recriado em cada tentativa. Uma chave da ordem identifica o objeto; uma chave do evento identifica uma ocorrência. Misturar as duas impede distinguir uma primeira conclusão de uma conclusão posterior a uma reabertura.
Mantenha o conteúdo mínimo que permite ao consumidor entender o fato sem consultar estados futuros por acidente. Uma mensagem que contém apenas o identificador e manda buscar o registro atual pode observar uma ordem já reaberta, embora o evento se refira à conclusão anterior. Isso pode ser aceitável para uma tarefa que sempre reconstrói o estado mais recente, mas não para produzir um relatório daquela versão. Declare se o contrato transporta um retrato do fato ou apenas um aviso para atualização; são comportamentos diferentes.
Modele estados que expliquem o que está pendente
Uma outbox operacional precisa permitir perguntas simples: o evento ainda não foi tentado, está reservado por um publicador, foi confirmado pelo transporte ou exige intervenção? Escolha estados e timestamps que respondam a essas perguntas sem inferências frágeis. Armazene quantidade de tentativas, próxima elegibilidade e uma classificação de falha. Evite transformar uma mensagem de erro inteira na regra que determina a próxima ação, porque mudanças no texto do fornecedor podem alterar o comportamento do seu sistema.
Se vários publicadores trabalham ao mesmo tempo, estabeleça uma forma de reservar lotes sem selecionar indefinidamente os mesmos itens. A reserva precisa expirar ou ser recuperável quando o processo morre. Um campo de proprietário com prazo pode funcionar quando acompanhado de atualização condicional e regras de posse claras. A solução concreta deve ser testada sob concorrência no banco escolhido. Uma leitura seguida de alteração sem proteção pode entregar o mesmo lote a dois trabalhadores, mesmo que cada um pareça correto quando executado sozinho.
Não mantenha a transação que encerra a ordem aberta enquanto espera a rede externa. O objetivo da outbox é deixar a confirmação local curta e tornar o restante recuperável. Também não apresente “relatório entregue” ao usuário só porque a ordem foi salva. A tela pode informar “serviço concluído; relatório em preparação”, desde que esse seja o estado real. A diferença entre conclusão do trabalho e conclusão da comunicação deve aparecer nos pontos onde alguém decide cobrar, revisar ou atender o cliente.
Construa o publicador para sobreviver a confirmações incertas
O publicador seleciona pendências elegíveis, transmite cada evento com seu identificador estável e registra a confirmação recebida. Uma interrupção depois de o transporte aceitar a mensagem e antes de o publicador marcar o sucesso deixa uma incerteza local. Ao retomar, o evento poderá ser enviado novamente. Trate esse cenário como normal no desenho, não como uma exceção improvável. É justamente uma das janelas que um teste de desligamento controlado precisa reproduzir.
Defina limites de trabalho por lote, tempo de execução e concorrência. Um lote grande reduz alguma sobrecarga, mas pode aumentar a quantidade de itens retidos por uma instância lenta e dificultar a recuperação. Um lote pequeno facilita distribuição, porém pode exigir mais consultas. Meça esses efeitos com o volume esperado e com o banco disponível. A empresa fictícia não precisa publicar milhares de ordens por segundo; o requisito importante é que uma indisponibilidade pela manhã seja recuperada sem bloquear o fechamento da tarde.
Separe falhas transitórias de problemas que precisam de correção. Uma conexão interrompida pode permitir nova tentativa com espera crescente e variação de intervalo. Um contrato rejeitado por campo inválido exige investigação do produtor ou do consumidor. Repetir o mesmo conteúdo inválido sem limite só consome capacidade. Registre a razão de suspensão e ofereça uma operação controlada para retomar após a correção. A equipe deve saber se está aguardando recuperação externa ou se alguém precisa agir.
Faça o consumidor reconhecer repetição antes do efeito
O consumidor precisa definir o que significa já ter aplicado determinado evento. Para o gerador de relatórios fictício, uma chave composta por consumidor e identificador do evento pode registrar processamento. A proteção precisa alcançar o efeito que se quer evitar. Gravar “recebido” antes de produzir o relatório e nunca retomar uma execução interrompida perde trabalho. Produzir o relatório e só depois anotar, sem qualquer proteção adicional, pode duplicá-lo. Examine cada janela de falha com a mesma disciplina usada na origem.
Quando o efeito e o registro de processamento cabem no mesmo banco, pode ser possível confirmá-los juntos. Se o efeito é externo, como enviar um documento por outro fornecedor, será necessário um contrato próprio de confirmação e recuperação. Não declare entrega exatamente uma vez apenas porque há uma tabela de eventos processados. O nome da tabela não garante atomicidade com ações fora dela. Documente o comportamento de repetição de cada consumidor e teste com interrupções no momento relevante.
Projete o relatório como um recurso ligado à versão da ordem, quando isso corresponder à regra do negócio. Assim, uma segunda entrega do mesmo evento pode localizar o resultado já preparado e concluir sem criar outro documento. Uma reabertura seguida de nova conclusão produz outra versão e outra decisão de relatório. O usuário deve conseguir diferenciar “reprocessar a mesma conclusão” de “emitir uma revisão”. Essa distinção reduz correções manuais e ajuda o suporte a explicar o histórico.
Preserve a ordem necessária sem serializar a empresa inteira
Determine onde a ordem importa. Eventos de uma mesma ordem de serviço podem exigir sequência: abertura, conclusão, reabertura e nova conclusão. Eventos de ordens independentes normalmente não precisam esperar uns pelos outros. Um único fluxo serial pode simplificar uma primeira implementação, mas também faz uma mensagem defeituosa bloquear todo o trabalho. A escolha deve seguir a relação de dependência real, não a conveniência de numerar tudo em uma lista global.
Inclua uma versão monotônica por objeto quando o produtor conseguir garanti-la. O consumidor poderá identificar uma atualização antiga, uma repetição ou uma lacuna. O que fazer com a lacuna depende do contrato: aguardar a versão ausente, consultar uma reconstrução autorizada ou encaminhar para recuperação. Descartar automaticamente qualquer mensagem que chegou fora de ordem pode eliminar um fato necessário. Aplicar sempre a última mensagem recebida também é incorreto quando a ordem de chegada difere da ordem de ocorrência.
No exemplo fictício, o painel operacional só precisa mostrar o estado mais recente e pode reconstruí-lo consultando a origem. O arquivo de relatórios, por outro lado, precisa preservar cada revisão aprovada. Esses dois consumidores podem receber os mesmos eventos e ter regras de processamento distintas. Escreva essa diferença na documentação do contrato. Ao desenvolver uma integração, a Tironi Tech pode ajudar a separar atualização de estado de preservação de fatos, evitando que uma convenção técnica substitua uma decisão operacional.
Observe atraso, crescimento e recuperação do acúmulo
Contar erros não basta. Um publicador parado pode deixar de gerar erros e ainda assim acumular trabalho. Acompanhe quantidade de pendências, idade da pendência mais antiga, ritmo de entrada e ritmo de publicação. Separe eventos suspensos de eventos ainda elegíveis. Uma fila pequena com um item antigo pode indicar uma ocorrência esquecida; uma fila grande que diminui de forma sustentada após uma interrupção pode estar em recuperação saudável. A leitura precisa considerar o comportamento do processo.
Estabeleça uma expectativa de atraso ligada à rotina. Se o relatório é revisado ao final do expediente, alguns minutos de espera podem ser aceitáveis, mas uma pendência atravessando o fechamento exige atenção. Esse prazo é uma decisão local, não uma propriedade do padrão outbox. Informe a expectativa em linguagem operacional e mantenha um caminho para consultar a ordem específica. Um gráfico agregado ajuda a detectar o problema; o suporte ainda precisa descobrir o que aconteceu com um caso individual.
Planeje capacidade de recuperação. Depois de duas horas sem publicação, o sistema precisa processar entradas novas e o acumulado. Aumentar concorrência sem limite pode derrubar o consumidor e prolongar o incidente. Teste uma rampa controlada, acompanhe latência e erros no destino e reduza o ritmo quando necessário. Defina quem decide a prioridade entre eventos antigos e recentes se o contrato permitir. Uma estratégia de recuperação precisa ser uma rotina ensaiada, não uma improvisação baseada em reiniciar trabalhadores repetidamente.
Teste falhas e estabeleça uma política de retenção
Monte uma matriz de testes com pontos de interrupção: antes da transação, antes da confirmação, depois da confirmação local, depois da aceitação pelo transporte e durante o efeito no consumidor. Para cada ponto, anote o estado esperado da ordem, da outbox e do resultado. Teste também mensagem repetida, versão desconhecida, consumidor indisponível e publicador concorrente. Os testes são úteis quando comprovam invariantes de negócio, como nenhuma conclusão confirmada ficar sem intenção de publicação, e não apenas quando verificam que uma função foi chamada.
Decida por quanto tempo manter eventos publicados e registros de processamento. Esse período precisa considerar recuperação, auditoria, volume e informação sensível. Guardar tudo para sempre aumenta custo e exposição; apagar cedo demais limita investigação e repetição controlada. Se um consumidor pode ficar desconectado por vários dias, essa possibilidade precisa ser compatível com a retenção e com um mecanismo alternativo de reconstrução. Documente o que é recuperável depois do prazo e o que não é.
Finalize com um procedimento de intervenção: como localizar um evento, examinar sua versão, corrigir a causa e solicitar reprocessamento sem alterar sua identidade. Mudanças no conteúdo de um evento histórico devem ser tratadas com cuidado, porque consumidores podem já ter visto a versão anterior. Muitas vezes é melhor publicar uma correção explícita. A outbox entrega valor quando a equipe consegue enxergar e resolver pendências; ela não substitui a definição de contratos, o comportamento dos consumidores nem a observação da operação completa.
Como enquadrar outbox transacional como uma decisão operacional
Antes de investir em outbox transacional, descreva o problema sem usar o nome de uma ferramenta. Registre quem inicia o processo, qual informação chega, onde ela é consultada, quem decide o próximo passo e qual resultado precisa ficar gravado. Esse recorte impede que uma iniciativa ampla demais misture aquisição, atendimento, venda e suporte em uma única promessa. O primeiro desenho deve mostrar um caso completo, inclusive exceções, espera e transferência de responsabilidade. A meta inicial é grave a mudança e o evento na mesma transação local., com uma fronteira que a equipe consiga explicar e testar.
Use conversas, pedidos, tarefas e perdas reais para confirmar o diagnóstico de outbox transacional. Uma amostra útil combina casos concluídos, abandonados, reabertos e encaminhados. Em cada caso, marque a necessidade apresentada, a primeira resposta útil, as fontes consultadas, as correções feitas e o desfecho conhecido. O objetivo não é encontrar exemplos que justifiquem uma solução já escolhida; é descobrir em qual etapa tempo, informação ou responsabilidade deixam de avançar. Se causas diferentes aparecem com frequência, elas devem virar fluxos ou regras distintas.
Transforme o diagnóstico em critérios de aceite. Para outbox transacional, um critério deve ser observável por outra pessoa: informação recuperada da fonte correta, registro criado com campos completos, encaminhamento feito para a fila adequada ou próxima ação combinada com o cliente. Evite critérios vagos como experiência melhor ou uso de IA. Eles podem orientar a intenção, mas não permitem verificar o funcionamento. O aceite também precisa declarar o que não será automatizado e como a operação continua quando uma dependência estiver indisponível.
Perguntas frequentes
A outbox elimina mensagens repetidas?
Não. Uma falha após publicar e antes de marcar a publicação pode levar ao reenvio. O consumidor precisa reconhecer o identificador do evento e evitar repetir o efeito.
Outbox exige um produto específico de fila?
Não. O padrão pode ser implementado com diferentes bancos e meios de transporte. É necessário verificar as garantias de transação, confirmação e entrega dos componentes escolhidos.
Posso apagar o evento assim que publiquei?
A retenção depende da auditoria, da recuperação e dos contratos com consumidores. Publicado não prova que todos aplicaram o efeito; defina a evidência necessária antes de eliminar registros.
Torne suas integrações recuperáveis
O ChatBô pode desenvolver publicadores, consumidores e acompanhamento de eventos para conectar suas rotinas sem esconder pendências operacionais.
Avaliar minha arquitetura de eventos