Arquitetura · Integrações · Critérios de aceite
Idempotência em integrações ERP: repetir a mensagem sem repetir a operação
O consumidor salvou o envio de um pedido. Antes de confirmar a mensagem ao transporte, o processo caiu. Na nova tentativa, o mesmo evento chegou outra vez. O sistema precisa reconhecer o resultado já confirmado.
O problema começa depois do caminho feliz
Em uma integração entre ERP e expedição, uma mensagem repetida pode gerar uma segunda ordem, repetir uma reserva ou produzir uma divergência operacional. Antes de escolher uma ferramenta, defina o efeito que deve acontecer uma única vez e o identificador que permite reconhecer sua repetição.
Este projeto usa três bancos SQLite separados: ERP fictício, transporte local e consumidor. Ele demonstra uma decisão de arquitetura e seus testes. Não acessa SAP, SQS, sistemas de clientes ou dados de produção.
Explore o cenário
Duas tentativas. Um efeito de envio.
Simulação visual, sem servidor ou banco real. Clique em sequência para observar a decisão; os testes Python abaixo são a evidência executável.
- Gravar o envio, mas simular falha antes do ACK.
- Reentregar o mesmo evento.
- Cancelar e receber uma atualização antiga.
Pronto: pedido fictício criado, versão 1.
A decisão: confirmar o efeito e a deduplicação juntos
O consumidor usa a chave (consumer, event_id). O mesmo ID com conteúdo diferente é um conflito; não pode desaparecer silenciosamente como se fosse uma repetição normal. Por isso, o laboratório também compara um fingerprint do payload.
- Abrir uma transação local e verificar a identidade do evento.
- Validar a versão do pedido e as regras de estado.
- Gravar estado, efeito local e resultado de processamento na mesma transação.
- Confirmar a mensagem ao transporte somente depois do commit.
Falha antes do commit reverte tudo. Falha depois do commit e antes do ACK deixa o resultado persistido: a nova tentativa encontra a inbox e retorna duplicate, sem repetir o efeito. O teste de reinício usa um processo Python separado, não apenas um conjunto em memória.
Por que existe uma outbox na origem?
O ERP fictício grava a mudança do pedido e a intenção de publicar o evento juntos. O relay entrega ao transporte e depois marca a outbox. Se cair entre esses passos, pode entregar novamente. A outbox trata a janela de perda na origem; a idempotência continua necessária no consumidor.
E as mensagens fora de ordem?
Neste cenário, uma versão antiga é registrada como stale, sem regredir o pedido. Uma versão futura com lacuna exige recuperar a dependência e tentar novamente. Cancelamento é terminal. Essas políticas são explícitas e testadas, mas devem ser definidas com o negócio em cada integração.
O que foi executado
14 testes automatizados passaram no ambiente de desenvolvimento. O resultado não mede desempenho, disponibilidade nem economia em clientes. A revisão externa permanece pendente.
| Cenário | Evidência observada |
|---|---|
| 16 entregas concorrentes do mesmo evento | 1 aplicação e 15 duplicatas; um efeito local |
| Falha antes do commit | Estado, efeito e inbox revertidos; nova tentativa pode aplicar |
| Commit seguido de falha no ACK | Outro processo reconhece o evento persistido; não repete o efeito |
| Falha no relay após entrega | Transporte recebe novamente; consumidor deduplica |
| Evento antigo após cancelamento | Pedido permanece CANCELLED, versão 3 |
| Erro persistente e replay | Histórico preservado, causa corrigida e identidade original mantida |
A demonstração termina com três efeitos de negócio locais: criação, envio e cancelamento. O envio aparece uma vez, apesar das duas tentativas de entrega. Confira o JSON gerado pela execução e os testes completos.
Reproduza sem conta paga
Use Python 3.10 ou superior. Não é necessário instalar pacotes externos. Na pasta do projeto:
python -m unittest discover -s tests -v
python lab.py demo --output evidence/minha-execucao.json
Para inspecionar os bancos, use python lab.py demo --directory .runtime. O README explica a limpeza restrita dos arquivos gerados e os resultados esperados. O exemplo usa somente dados inventados.
Onde esta demonstração termina
- O efeito protegido está no mesmo banco da inbox. Uma chamada HTTP, pagamento ou e-mail externo exige estratégia própria.
- O transporte local não reproduz toda a semântica de um broker real, rede ou ambiente distribuído.
- SQLite serializa a escrita. O teste local não comprova escala, SLA ou compatibilidade direta com SAP.
- Retenção de deduplicação, observabilidade, autenticação e recuperação operacional precisam ser projetadas para produção.
- Não há promessa de exactly-once de ponta a ponta, homologação de cliente ou revisão independente concluída.
O papel da liderança técnica nessa conversa
A decisão precisa ser compreendida por quem desenvolve, testa e opera. O Tech Lead explicita o efeito protegido, a janela de falha e o limite da evidência; gestão do projeto coordena dependências; operação e responsáveis de negócio definem o aceite. Um teste de caminho feliz não encerra essa discussão.
Continue a leitura
- Gestão de dependências em projetos de TI
- O papel do Tech Lead entre arquitetura, projetos e negócio
- Conversar sobre arquitetura e entregas no LinkedIn
Referências técnicas
Laboratório autoral desenvolvido com assistência de IA e testes automatizados. Exemplos fictícios; não representa AtisWork, CPFL Energia ou clientes. Última revisão: 9 de novembro de 2026.