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