Pergunta 42 de 50
Como evitar processamento duplicado?
Pergunta
"Na prática, como você evitaria processamento duplicado de mensagens em um consumer Kafka?"
O que o entrevistador quer avaliar
A pergunta mais aplicada de toda essa seção — quer ver o padrão de implementação real, com atenção específica à atomicidade sob concorrência, não só "eu uso um ID único".
Resposta rápida
Uso um eventId único por evento (gerado pelo producer), e no consumer, verifico e insiro esse eventId em
uma tabela de controle (eventos_processados) com constraint de unicidade — na mesma transação que aplica
o efeito de negócio. Se a inserção falhar por duplicidade, ignoro o evento com segurança.
Resposta nível Sênior
O ponto crítico é a atomicidade: a checagem de "já processei esse eventId?" e a aplicação do efeito
(creditar, debitar, gravar) precisam acontecer na mesma transação de banco. Se forem passos separados — uma
consulta seguida de uma atualização —, existe uma janela de corrida onde duas execuções concorrentes podem
checar "não existe" ao mesmo tempo e aplicar o efeito duas vezes antes que qualquer uma grave o eventId. A
constraint de unicidade do banco, não uma checagem em código de aplicação, é a garantia real. Para operações
já naturalmente idempotentes (um upsert que sempre grava o mesmo valor final), esse controle explícito pode
ser dispensado — mas para operações que acumulam estado (creditar, incrementar), ele é obrigatório.
Explicação aprofundada
Veja "O padrão: eventId + constraint de unicidade" e "Atomicidade" no Capítulo 11.
Exemplo financeiro
@Transactional
public void creditarPix(PixRecebidoEvent evento) {
try {
eventosProcessadosRepository.insert(evento.getEventId());
} catch (DataIntegrityViolationException e) {
return; // já processado
}
contaRepository.creditar(evento.getContaId(), evento.getValor());
}
"Basta checar se o ID já existe antes de processar"
Checagem prévia sem estar na mesma transação do efeito é vulnerável a condição de corrida. A resposta completa sempre menciona a atomicidade via transação — não apenas a existência de um identificador único.
Pode vir a seguir
Prováveis follow-ups: "e se dois consumers processarem o mesmo evento ao mesmo tempo?" e "como isso se relaciona com o Outbox Pattern?".
Capítulos relacionados