[Conceito] - Lock Pessimista x Otimista: Desenvolvendo Senso Analítico
Published: 2024-01-03 04:51:43

> Conteúdo original em https://twitter.com/zanfranceschi/status/1742406772139430162

---
Ei dev,

Esses dias postei provocações sobre lock otimista x pessimista. Alguns disseram que até certo nível de concorrência/conflito uma opção vale mais a pena que outra.

Vamos pensar nisso juntos? Não vou dar uma resposta – quero apenas aprofundar nosso senso analítico.

↓

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2007982atjkr69f0wvk.png)

https://twitter.com/zanfranceschi/status/1738927304372371552

---

DISCLAIMER: Essa thread vale mais a pena se você souber pelo menos por cima o que é um lock otimista e um lock pessimista de banco de dados. Se não souber e mesmo assim quiser continuar lendo, tem todo meu apoio. rsrs

Mas sério, dá uma pesquisada – não são conceitos difíceis.

---

→ O primeiro passo é termos números concretos. Bora pensar um pouco sobre a probabilidade de conflitos. Pra isso, vamos imaginar o seguinte cenário: requisições simultâneas para comprar algum produto – para simplicidade, vamos imaginar que todos os produtos vendem a mesma coisa.

---

Vamos então supor que temos 10 requisições simultâneas para 8 produtos diferentes. Queremos calcular a probabilidade de p.ex. 2 dessas requisições concorrerem para afetar o estoque do mesmo produto. Lembre-se, é um cenário síncrono e simplista!

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jt300ok8eocijz7uhngi.png)

---

Para chegar nisso, precisamos achar o número de combinações de conflitos (R ÷ C × P × P ^ (R - C)) e dividí-lo pelo número total de combinações (P ^ R), onde R = número de requisições simultâneas, P = produtos disponíveis, C = número de conflitos.

R ÷ C × P × P ^ (R - C) / P ^ R

---

Meio mala essa fórmula, eu sei. O resultado dela é 0,625 – ou seja, ~62% de chance de conflito/concorrência com os parâmetros mencionados. Se quiséssemos a probabilidade com, p.ex., 3 conflitos, essa porcentagem cairia para ~5%; com 4, iria para ~0,4%. Com 5, 4,8828125E-4. 🥲

---

Agora a gente precisa entender quanto tempo >MAIS OU MENOS< cada abordagem – pessimista e otimista – leva pra processar cada requisição.

---

Vamos começar pela abordagem pessimista chutando um valor para o processamento da requisição: ~10ms. Como existe a concorrência de 2 requisições, a gente teria por cima um tempo de processamento de ~20ms para as 10 requisições simultâneas.

---

Se fossem 3 conflitos, ~30ms; 4, ~40ms para 10 requisições; e assim por diante. Por favor, note que essa é uma estimativa simplificada.

---

Nesse cenário pessimista, a gente geralmente precisa de menos mecanismos para tratar problemas de inconsistência nos dados.

Lembre-se, estamos fazendo mais locks para termos mais consistência de dados ao preço de uma possível maior contenção – menos paralelismo.

---

Bora pro otimismo – aqui a porca torce o rabo. No cenário Poliana, a gente geralmente introduz mais mecanismos para compensar os conflitos/não possibilidade de realização dos comandos no banco. Isso pode se traduzir em retentativas, rollbacks, mensagens de erro, etc, e etc.

---

Pra nossa comparação fazer sentido, deveríamos incluir o tempo de processamento desses possíveis mecanismos de compensação. Por exemplo, 1 retentativa automática pode levar o dobro do tempo; 2 retentativas o triplo; devolver uma mensagem de erro pode ser muito rápido, etc.

---

Se devolver uma mensagem de erro, talvez não haja acréscimo de tempo como há para uma compensação automática, mas talvez o usuário final o irá fazer manualmente gerando mais requisições subsequentes. Isso tudo precisa ser considerado. 🤔

---

A maior diferença entre os dois cenários é que o pessimista é (mais ou menos) mais serial durante os conflitos (porque há o lock de mais registros) e o cenário pessimista é menos serial porque um processo interfere menos em outros (não há lock por toda a transação).

---

Uma estimativa super simplificada do cenário otimista, onde apenas uma mensagem de erro é devolvida, se tivéssemos 2, 3 ou N conflitos simultâneos e cada processamento levasse ~10ms, nós ainda teríamos os mesmos ~10ms para as 10 requisições simultâneas – com ou sem conflitos.

---

Vou deixar pra você fazer um exercício sobre como calcular o cenário otimista duma maneira melhor, pois estou com 2% de life estatística. 🙂

Espero que agora você tenha pelo menos uma intuição sobre alguns cálculos para obter números relevantes.

---

Obviamente, num cenário real muitas outras dimensões seriam consideradas. P.ex.: produtos que vendem mais (ponderação), picos de acesso, promoções, publicidade, etc. Em outros domínios, outras dimensões devem ser consideradas.

---

O resumo é o seguinte:

\- Tente se basear em números;
\- Entenda as dimensões específicas do seu problema/domínio;
\- Faça experimentos! A prática muitas vezes nos dá insights muito mais tangíveis do que algumas teorias, ainda mais quando não temos experiência.

---

Talvez eu tenha sido filosófico/genérico demais nessa thread porque na verdade muita coisa nela serve pra outras coisas não relacionadas a simplesmente escolher entre usar uma abordagem de lock pessimista x otimista de banco de dados (inclusive, existem abordagens híbridas!).

---

Mas olha só: muito obrigado se você chegou até aqui – mesmo!

Um abraço pra quem é de abraço e um beijo pra quem é de beijo. ♥️