Pular para o conteudo principal

Deduplicação e Idempotencia no Código

Como impedir que retry, mensagem repetida e clique duplicado virem efeito colateral duplo dentro da implementação real.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

O problema

Uma operação chega duas vezes e o sistema faz duas vezes.

Esse resumo parece bobo, mas ele explica muito incidente real.

Exemplos comuns:

  • usuário clica duas vezes em “pagar”
  • cliente recebe timeout e faz retry
  • webhook chega duplicado
  • mensagem reaparece na fila

Se o código foi escrito com a fantasia de “isso aqui vai chegar uma vez só”, o estrago aparece rápido:

  • cobrança dupla
  • email duplicado
  • estoque baixado duas vezes
  • job processado de novo

Modelo mental

Tem duas ideias parecidas, mas não iguais:

  • deduplicação
  • idempotencia

Deduplicação responde:

eu consigo reconhecer que essa mesma intenção já apareceu?

Idempotencia responde:

se ela aparecer de novo, o efeito final continua seguro?

Em muitos sistemas as duas andam juntas.

Mas vale separar para pensar melhor.

Quebrando o problema

Onde repetição nasce

Repetição pode nascer em vários pontos:

  • no usuário
  • no cliente HTTP
  • na rede
  • no broker
  • no próprio backend apos falha parcial

Por isso proteção boa não depende de “educar o cliente”.

Ela entra no desenho do sistema.

Deduplicação reconhece a mesma intenção

Para deduplicar, você precisa de um identificador que represente aquela operação.

Pode ser:

  • idempotency_key
  • event_id
  • job_id
  • combinação de campos de negócio

O ponto e conseguir responder:

  • isso e realmente a mesma tentativa?
  • ou e uma operação nova parecida?

Sem essa distincao, você corre o risco de colapsar coisas diferentes ou repetir o que era igual.

Idempotencia protege o efeito final

Reconhecer repetição não basta.

O sistema precisa garantir que repetir não aplique dano novo.

Exemplos:

  • se o pagamento já foi criado, devolve o resultado anterior
  • se o evento já foi aplicado, não baixa estoque de novo
  • se o email daquele job já foi enviado, não dispara outra vez

Repare no foco:

não e impedir a função de rodar para sempre.

E impedir efeito colateral duplo.

Onde colocar a proteção

A proteção boa costuma morar perto do efeito importante.

Exemplos:

  • cobrança: perto da escrita da cobrança
  • consumo de evento: junto do registro de evento processado
  • job: junto da mudança de status e persistencia do resultado

Se você deixa a proteção só na borda, mas o efeito acontece mais fundo, a janela para bug continua aberta.

Chave sem persistencia não resolve

Outro erro comum e gerar chave bonita e não registrar nada com ela.

Se o sistema não persiste:

  • que a operação já ocorreu
  • qual foi o resultado
  • ou qual evento já foi consumido

entao a chave vira só decoração.

Exemplo simples

Imagine um webhook payment.confirmed com event_id=evt_9.

Fluxo ruim:

  1. consumidor recebe evento
  2. baixa estoque
  3. envia email
  4. confirma consumo

Se o processo cai depois do passo 3 e antes da confirmação, a mensagem pode reaparecer.

Sem proteção, o estoque cai de novo e o email duplica.

Fluxo melhor:

  1. consumidor verifica se evt_9 já foi processado
  2. se não foi, aplica o efeito e registra evt_9
  3. se já foi, sai sem repetir dano

Dependendo do caso, o registro do event_id e o efeito importante precisam acontecer na mesma transação ou no arranjo mais confiavel que o sistema permitir.

Não porque o sistema vai ficar perfeito.

Mas porque a janela de duplicidade cai bastante.

Erros comuns

  • Confiar só em desabilitar botao no frontend.
  • Achar que deduplicação e a mesma coisa que lock.
  • Guardar identificador sem vincular ao efeito aplicado.
  • Fazer retry agressivo sem plano para repetição.
  • Usar hash improvisado de payload e chamar isso de certeza de unicidade.

Como um senior pensa

Quem tem mais experiência não pergunta primeiro “como evitar repetir request?”.

Pergunta isto:

“Se repetir, onde o dano acontece e como eu provo para o código que essa intenção já foi aplicada?”

Essa mudança de foco e forte.

Sai da ilusão de controle da entrada e vai para a segurança do efeito.

O que o entrevistador quer ver

Em entrevista, esse assunto aparece muito em pagamento, webhook, fila e job assíncrono.

O avaliador quer ver se você consegue sair da teoria e descer para implementação.

Sinais bons:

  • você diferencia deduplicação de idempotencia
  • fala de chave ou identificador de negócio
  • coloca a proteção perto da escrita importante
  • menciona retry e reprocessamento como comportamento normal

Uma resposta forte costuma soar assim:

“Eu assumo que a mesma intenção pode chegar de novo. Entao guardo um identificador estavel, verifico se já foi aplicado e faco a escrita importante de forma que repetir não gere efeito novo.”

Sistema resiliente não e o que nunca recebe repetição. E o que não entra em panico quando ela aparece.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Próximo artigo Exactly-once Quase Nunca Existe, Como Pensar Direito Sobre Isso Artigo anterior Como Explicar Trade-offs de Consistência em Entrevista

Continue explorando

Artigos relacionados