«Exatamente uma vez» é uma mentira: conceber integrações para duplicados

Três cópias do mesmo bloco de mensagem a convergir num único bloco processado

Em algum lugar de todos os contratos de integração existe uma frase do tipo «cada encomenda será transmitida exatamente uma vez». Nunca foi verdade, nem uma única vez. A rede particionou a meio de um pedido e o remetente tentou novamente; a fila reentregou a mensagem após uma falha do consumidor; um operador de armazém carregou duas vezes no botão de exportação. Os duplicados não são um modo de falha - são meteorologia.

Chaves de idempotência, escolhidas com cuidado

A solução é antiga e pouco glamorosa: cada mensagem transporta uma chave, e o processamento não faz nada quando essa chave já foi vista. As decisões interessantes estão todas na escolha da chave.

  • As chaves naturais superam as geradas. Uma sincronização de encomendas com chave order_id + status sobrevive à regeneração da outbox pelo remetente; um UUID aleatório gerado no momento do envio não sobrevive.
  • Delimite a chave ao efeito, não à mensagem. Se uma mensagem cria uma fatura e reserva stock, são dois efeitos com duas chaves - caso contrário, uma falha parcial deixa-o incapaz de repetir com segurança qualquer um dos dois.
  • Faça expirar as chaves deliberadamente. Um repositório de deduplicação que cresce indefinidamente é uma bomba-relógio; um que expira demasiado cedo reintroduz duplicados. Por defeito, usamos 3× o horizonte máximo de nova tentativa do remetente.

O teste que importa

Todas as integrações que entregamos passam pelo que internamente chamamos o teste do duplo toque: reproduzir todo o registo de mensagens de ontem contra o sistema de hoje, duas vezes, e comparar o estado resultante. Se algo mudou na segunda passagem, o pipeline não está pronto.

É um teste brutal e falha constantemente durante o desenvolvimento - em timestamps, em campos de auditoria «criado por», em contadores de sequência. Cada falha é um ponto onde uma reentrega às 3 da manhã teria silenciosamente corrompido dados. Sai muito mais barato detetá-lo em desenvolvimento do que em produção.