🧠 Consulta Guiada e Adaptativa
Uma conversa entre Matondo Pedro e João
Tema: Race Condition → Lock
👨🏫 João:
Vamos começar com um problema real.
Imagina uma loja que tem apenas uma unidade de determinado produto.
O João e a Maria entram na loja exatamente ao mesmo tempo e os dois tentam comprar esse produto.
O que achas que pode acontecer?
👨💻 Matondo Pedro:
Os dois podem tentar comprar o mesmo produto e isso pode gerar um erro.
👨🏫 João:
Exatamente. Mas vamos olhar com mais cuidado.
Imagina que o stock é:
stock = 1
O João consulta:
stock > 0 → sim
Ao mesmo tempo, a Maria também consulta:
stock > 0 → sim
Os dois recebem uma resposta válida.
O que pode acontecer depois?
👨💻 Matondo Pedro:
Talvez a Maria fique com “-1”?
👨🏫 João:
Não necessariamente.
O problema mais perigoso é que os dois podem confirmar a compra, mesmo existindo apenas uma unidade física do produto.
Cada operação, isoladamente, parecia válida.
O problema surgiu porque elas aconteceram ao mesmo tempo sobre o mesmo estado compartilhado.
É uma Race Condition.
👨💻 Matondo Pedro:
É como se os dados fossem replicados para os dois utilizadores.
👨🏫 João:
A ideia está próxima, mas pensa de outra forma.
Imagina uma sala com apenas uma porta.
Duas pessoas chegam ao mesmo tempo.
As duas perguntam:
«“A sala está livre?”»
As duas recebem:
«“Sim.”»
Antes que uma delas entre, a outra também entra.
O problema não é que a sala foi “replicada”.
O problema é que duas pessoas observaram o mesmo estado antes de qualquer uma conseguir alterá-lo.
👨💻 Matondo Pedro:
Então o “if (stock > 0)” não resolve?
👨🏫 João:
Exatamente.
Porque podemos ter:
João: if (stock > 0) → SIM
Maria: if (stock > 0) → SIM
Os dois passaram pela condição.
Então, como poderíamos impedir que duas operações conflitantes trabalhassem simultaneamente sobre o mesmo recurso?
👨💻 Matondo Pedro:
Poderíamos colocar numa fila.
👨🏫 João:
Sim. Uma fila poderia serializar as operações.
Mas imagina uma loja com 10.000 clientes.
Seria necessário colocar todos numa única fila?
👨💻 Matondo Pedro:
Não. Só os que estão tentando comprar o mesmo produto.
👨🏫 João:
Exatamente.
Então precisamos de uma forma de controlar o acesso ao recurso que está em conflito, e não bloquear o sistema inteiro.
O que poderíamos usar para isso?
👨💻 Matondo Pedro:
Um lock.
Como colocar um cadeado no produto.
👨🏫 João:
Perfeito. 🔒
E onde faria sentido esse lock existir?
👨💻 Matondo Pedro:
No banco de dados.
👨🏫 João:
Exatamente.
Por exemplo:
SELECT *
FROM products
WHERE id = 1
FOR UPDATE;
Esse “FOR UPDATE” permite bloquear a linha que estamos prestes a modificar.
Assim, outra transação que precise de um lock incompatível nessa mesma linha terá de esperar.
E agora aparece uma nova pergunta:
O lock sozinho é suficiente para representar toda a compra?
🎯 O método
Nesta conversa, não começámos pela definição de Race Condition ou Lock.
Começámos por um problema real, fizemos perguntas, testámos hipóteses e fomos descobrindo os conceitos à medida que eles se tornavam necessários.
🧠 Consulta Guiada e Adaptativa: começar pelo problema e conduzir a pessoa até à descoberta da solução.