16 de Maio de 2025
O que Acontece Quando Duas Pessoas Clicam ao Mesmo Tempo
Como pensar concorrência a partir de disputa real por estado, sem cair direto em teoria ou em remendo no frontend.
Andrews Ribeiro
Founder & Engineer
3 min Intermediario Sistemas
O problema
O time testa fluxo feliz sozinho e tudo parece certo.
Mas o mundo real não espera sua vez.
Duas pessoas tentam comprar o ultimo item. Dois operadores aprovam o mesmo reembolso. O mesmo usuário clica duas vezes porque a tela travou. E de repente o sistema promete algo que só podia acontecer uma vez.
Quase sempre o bug já estava la. A concorrência só revelou.
Modelo mental
Quando duas pessoas clicam ao mesmo tempo, a pergunta principal não e sobre clique.
E sobre estado compartilhado.
O que realmente importa e isto:
existe alguma verdade do negócio que duas execuções paralelas podem quebrar?
Exemplos:
- só existe uma ultima unidade
- saldo não pode ficar negativo
- pedido não pode ser pago duas vezes
- o mesmo assento não pode ser reservado por duas pessoas
Se a resposta for sim, o sistema precisa proteger essa verdade mesmo sob disputa.
Quebrando o problema
O frontend não e a defesa final
Desabilitar botao, mostrar loading e evitar duplo clique ajudam muito a experiência.
Mas isso não resolve o problema de corretude.
Porque ainda podem existir:
- duas abas
- dois usuários
- retry automático
- request repetida por timeout
- outro serviço chamando a mesma operação
Proteção real mora no backend ou no armazenamento.
O perigo esta no read, decide, write
Muita quebra nasce deste fluxo:
- ler estado atual
- decidir baseado nele
- gravar novo estado
Se duas execuções fazem isso em paralelo com o mesmo dado antigo, as duas acreditam que podem seguir.
O erro não e uma linha visivelmente absurda.
O erro e assumir que a leitura continua valida até a escrita final.
Nomeie a invariavel antes da ferramenta
Antes de escolher mecanismo, diga o que não pode quebrar.
Exemplos de invariavel:
- estoque nunca abaixo de zero
- uma reserva por recurso
- uma cobrança por intenção de pagamento
Quando a invariavel fica clara, a solução melhora muito.
Exemplo simples
Imagine um ingresso com apenas 1 vaga restante.
Usuário A e usuário B clicam em “comprar” quase ao mesmo tempo.
Os dois requests:
- consultam disponibilidade
- encontram
1 - concluem que podem reservar
- seguem para gravar
Se o sistema só faz leitura e depois um update simples demais, você vende duas vezes.
Algumas respostas possiveis:
- update atomico no banco
- lock sobre aquele recurso
- fila para serializar disputa por chave
- expiração de reserva temporária
Agora imagine outro caso: o usuário clicou duas vezes no mesmo botao de pagar.
Aqui pode ser menos sobre disputa entre duas pessoas e mais sobre repetição da mesma intenção.
Talvez idempotencia seja a peca mais importante.
Mesmo sintoma aparente. Problemas diferentes por baixo.
Erros comuns
- Resolver só na UI e chamar isso de proteção.
- Falar “isso dificilmente acontece” sem medir impacto.
- Usar lock em tudo sem pensar em throughput.
- Jogar retry por cima de operação não idempotente.
- Corrigir um caso visível sem modelar a invariavel do negócio.
Como um senior pensa
Quem tem mais experiência normalmente troca a pergunta.
Em vez de perguntar “como evito duplo clique?”, pergunta:
“Quando duas execuções competem pela mesma verdade, qual mecanismo garante que o estado final continua valido?”
Essa mudança parece pequena. Mas muda tudo.
Porque você sai de sintoma de interface e vai para corretude de sistema.
O que o entrevistador quer ver
Em entrevista, esse tema aparece muito porque revela rápido se você pensa em sistema real.
O avaliador quer ver se você:
- identifica estado compartilhado
- nomeia a invariavel de negócio
- entende por que frontend sozinho não basta
- escolhe mecanismo coerente com a disputa
Uma resposta forte costuma soar assim:
“Se duas pessoas clicam ao mesmo tempo, eu não olho primeiro para o botao. Eu olho para a regra que não pode quebrar. A partir dela eu decido entre atomicidade, lock, fila ou idempotencia.”
Concorrência não cria a fragilidade. Ela expõe a fragilidade que o fluxo já tinha.
Resumo rápido
O que vale manter na cabeça
- Concorrência real aparece quando duas execuções tentam preservar a mesma regra ao mesmo tempo.
- Desabilitar botao na UI melhora UX, mas não protege corretude no backend.
- O que importa e definir qual verdade não pode quebrar e proteger isso com o mecanismo certo.
- Atomicidade, lock, fila e idempotencia entram em problemas diferentes, não como sinonimos.
Checklist de pratica
Use isto ao responder
- Consigo explicar por que clique simultâneo vira problema de corretude e não de interface?
- Sei nomear qual invariavel do negócio precisa continuar verdadeira?
- Consigo sugerir quando usar operação atomica, lock ou idempotencia?
- Sei explicar esse tipo de bug em entrevista sem apelar para teoria solta?
Você concluiu este artigo
Próximo passo
Race condition na prática Próximo passo →Compartilhar esta página
Copie o link manualmente no campo abaixo.