trilha

System Design/02 - Componentes2 min

Idempotent Operations

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Uma operação é idempotente quando executá-la várias vezes produz o mesmo resultado que executá-la uma vez.

Isso importa porque, em rede, você nunca sabe se a requisição falhou ou se só a resposta se perdeu. O cliente que não recebe resposta tem duas opções: repetir (e arriscar duplicar) ou não repetir (e arriscar perder). Idempotência elimina o dilema.

Nos métodos HTTP

Método Idempotente? Seguro?
GET, HEAD Sim Sim (não altera)
PUT Sim — define o estado final Não
DELETE Sim — apagar de novo é no-op Não
POST Não Não
PATCH Depende (x = 5 sim; x += 1 não) Não

Como tornar uma operação idempotente

Técnica Como funciona
Chave de idempotência Cliente envia um UUID; o servidor guarda o resultado e devolve o mesmo em repetição
Chave natural Usar um ID de negócio como chave primária — a segunda escrita colide, não duplica
Escrita condicional INSERT ... ON CONFLICT DO NOTHING, compare-and-swap, ETag/If-Match
Formulação absoluta SET saldo = 100 em vez de saldo = saldo - 50
Tabela de deduplicação Registrar IDs já processados, com TTL

Trade-offs

Idempotência custa estado: alguém precisa lembrar o que já foi processado. Essa tabela cresce, precisa de TTL, e vira mais um componente com sua própria disponibilidade.

Há também uma janela de corrida: duas requisições com a mesma chave chegando simultaneamente exigem que a checagem e a gravação sejam atômicas — senão as duas passam. Um INSERT com constraint única resolve; um SELECT seguido de INSERT não.

A alternativa — entrega exactly-once no transporte — é mais cara e mais frágil. O consenso da indústria é at-least-once no transporte + idempotência no consumidor.

Exemplo prático

Um pagamento: o cliente envia POST /cobranca com header Idempotency-Key: 7f3a.... A rede cai antes da resposta chegar. O cliente repete com a mesma chave.

O servidor encontra a chave já registrada e devolve a resposta original, sem cobrar de novo. Sem a chave, a segunda tentativa criaria uma segunda cobrança — e o cliente seria debitado duas vezes por um problema de rede.

O mesmo padrão vale para consumidor de fila: como Message Queues entregam pelo menos uma vez, o worker precisa registrar o ID processado antes de considerar o trabalho concluído.

Relacionado


Parte de 02 - MOC Componentes · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas