Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
IT Security NachrichtenWenn Maschinen zu Zielen werden(01.10.2026 um 08:00 Uhr)
•••••••
IT NachrichtenBald in Deutschland? Tesla kündigt neues Model 3 an(01.10.2026 um 08:08 Uhr)
•••
IT Security NachrichtenWenn Maschinen zu Zielen werden(01.10.2026 um 08:00 Uhr)
•••••••
IT NachrichtenBald in Deutschland? Tesla kündigt neues Model 3 an(01.10.2026 um 08:08 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

Como descobri o Pessimistic Locking e por que isso mudou minha forma de pensar sobre concorrência

Recentemente participei de uma entrevista técnica do tipo whiteboard, e saí dela com algo muito mais valioso do que um possível “sim” ou “não”: aprendizado real…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

Recentemente participei de uma entrevista técnica do tipo whiteboard, e saí dela com algo muito mais valioso do que um possível “sim” ou “não”: aprendizado real, técnico e profundo.



Foi a partir de uma sugestão do próprio avaliador que entrei em contato com o conceito de Pessimistic Locking, e desde então mergulhei no tema para entender os riscos que sistemas financeiros enfrentam quando se trata de concorrência de dados.



Neste artigo, quero compartilhar esse processo — tanto o desafio apresentado, quanto os conceitos que aprendi depois, e como ter bons avaliadores faz toda a diferença para o crescimento profissional.









O desafio apresentado



Em um determinado momento da entrevista, o avaliador decidiu simular um caso real de construção de produto. A ideia era propor a criação de um POC - Proof of Concept (Prova de Conceito).



O projeto precisava ser simples e direto, pois a equipe estava em fase de validação do produto e procisava de algo funcional para testar o modelo de negócio com usuários o quanto antes.



Dentro desse contexto, me foi solicitado que o projetasse alguns endpoints essenciais para o sistema bancário proposto:



GET /contas/{id}/extrato Para consultar o extrato e saldo de uma conta



POST /transferencias Para permitir que um usuário envie dinheiro da conta A para a conta B.



A arquitetura deveria ser mínima, funcional e segura, e deveria atender a três pilares fundamentais:




  • Segurança dos dados e operações

  • Boas práticas REST para API


  • Consistência transacional, mesmo em um sistema ainda em fase inicial






Minhas escolhas e justificativas:




  • Usei GET para a leitura do extrato, pois é um verbo seguro e sem efeitos colateriais.

  • Usei POST para a criação da transferência, pois trata-se de uma operação que modifica o estado do sistema.

  • Os caminhos foram estruturados de forma RESTful, facilitando a compreensão e escalabilidade da API.



A proposta do avaliador era clara: mesmo sendo uma POC, o ssitema deveria se comportar como algo confiável, pois a ideia era colocar a prova um produto real, ainda que em fase de testes.



Até então, tudo parecia bem. Mas foi nesse momento que veio uma das perguntas mais importantes da entrevista, que elevou o nível do desafio:




“Como você garantiria que duas transferências simultâneas não fariam com que o mesmo saldo fosse usado duas vezes?”




E foi a partir dessa provocação que a entrevista tomou um novo rumo, um que me levou a buscar aprender mais sobre concorrência.






O que é Race Condition?



Uma race condition acontece quando duas ou mais operações acessam o mesmo recurso ao mesmo tempo e o resultado depende da ordem de execução



Por exemplo:




  • A conta de João possui R$ 100.00

  • Duas transferências de R$ 100.00 são disparadas ao mesmo tempo

  • Ambas leem o saldo, consideram suficiente e processam a transação



Nesse caso, João acaba transferindo R$ 200.00 com apenas R$ 100.00 de saldo



→ O sistema foi enganado por falta de controle de concorrência.






Como funcionam os locks no banco de dados?



Para evitar situações como a descrita acima, os bancos de dados implementam mecanismos de locks (bloqueio), que controlam o acesso concorrente a dados sensíveis.






O que é um lock?



Um lock impede que múltiplas transações leiam ou alterem os mesmo dados ao mesmo tempo. Ele pode ser aplicado em diferentes níveis e tipos:




  1. Shared lock (Leitura)




  • Permite múltiplas leituras simultâneas

  • Bloqueia a escrita enquanto está ativo.

  • Ideal para operações de leitura que exigem consistência




  1. Exclusive lock (Escrita)




  • Exclusivo: impede qualquer leitura ou escrita concorrente




  1. Lock de linha vs Lock de tabela




  • Linha: bloqueia apenas o registro necessário. Permite maior concorrência


  • Tabela: bloqueia a tabela inteira. Mais seguro, porém menos eficiente.







Locks e transações



Locks geralmente fazem parte de transações, que seguem as regras ACID:




  • Atomicidade

  • Consistência

  • Isolamento

  • Durabilidade



Dessa forma, os locks acabam garantindo o isolamento da transação, impedindo que operações concorrentes interfiram nos dados enquanto a transação está em andamento.






O que é Pessimistic Locking?



É uma abordagem onde os dados são bloqueados no momento da leitura, assumindo que há risco real de conflito.



SQL Exemplo:




BEGIN;
SELECT * FROM contas WHERE id = 1 FOR UPDATE;
-- realiza a transferência
COMMIT;






Esse comando bloqueia a linha da conta até que a transação finalize, impedindo que qualquer outra operação use esses dados simultaneamente.






Exemplo prático com Kotlin + Spring Boot






1. Entidade






import jakarta.persistence.Entity
import jakarta.persistence.Id
import java.math.BigDecimal

@Entity
data class Conta(
@Id val id: Long,
var saldo: BigDecimal
)









2. Repositório com lock pessimista






import br.com.pessimistic_locking.entity.Conta
import jakarta.persistence.LockModeType
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Lock
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository

@Repository
interface ContaRepository : JpaRepository<Conta, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT c FROM Conta c WHERE c.id = :id")
fun findByIdForUpdate(@Param("id") id: Long): Conta
}









3. Serviço de transferência






import br.com.pessimistic_locking.repository.ContaRepository
import jakarta.transaction.Transactional
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.math.BigDecimal

@Service
class ContaService(
@Autowired private val contaRepository: ContaRepository
) {

@Transactional
fun transferir(origemId: Long, destinoId: Long, valor: BigDecimal) {
val origem = contaRepository.findByIdForUpdate(origemId)
val destino = contaRepository.findByIdForUpdate(destinoId)

if (origem.saldo < valor) throw IllegalArgumentException("Saldo insuficiente")

origem.saldo -= valor
destino.saldo += valor

contaRepository.save(origem)
contaRepository.save(destino)
}
}









4. Controller






@Controller
@RequestMapping("/contas")
class ContaController(
private val service: ContaService
) {
@GetMapping("/{id}/extrato")
fun get(@PathVariable id: Long): ResponseEntity<Conta> = ResponseEntity.ok(service.extrato(id))
}









@Controller
@RequestMapping("/transferencias")
class TransferenciasController(
private val service: ContaService
) {
@PostMapping
fun post(@RequestBody body: RequestTransferencia): ResponseEntity<Void> {
service.transferir(
origemId = body.origemId,
destinoId = body.destinoId,
valor = body.valor
)
return ResponseEntity.ok().build()
}
}

data class RequestTransferencia(
val origemId: Long,
val destinoId: Long,
val valor: BigDecimal

)









5. Carga de contas na base de dados






INSERT INTO public.conta
(id, saldo)
VALUES(1, 100);

INSERT INTO public.conta
(id, saldo)
VALUES(2, 100);









5. Consultado extrato






curl --request GET \
--url http://localhost:8080/contas/1/extrato \
--header 'User-Agent: insomnia/11.0.0'









6. Executando transferência






#!/bin/bash

echo "Iniciando teste de concorrência com duas transferências simultâneas..."

# Requisição 1 (em background)
curl --request POST \
--url http://localhost:8080/transferencias \
--header 'Content-Type: application/json' \
--header 'User-Agent: insomnia/11.0.0' \
--data '{
"origemId": 1,
"destinoId": 2,
"valor": 100
}' &
PID1=$!

# Requisição 2 (em background)
curl --request POST \
--url http://localhost:8080/transferencias \
--header 'Content-Type: application/json' \
--header 'User-Agent: insomnia/11.0.0' \
--data '{
"origemId": 1,
"destinoId": 2,
"valor": 100
}' &
PID2=$!

# Aguardar as duas finalizarem
wait $PID1
wait $PID2

echo "Teste finalizado."









Limitações do Pessimistic Locking



Apesar de poderoso essa abordagem possui seus trade-offs:




  1. Desempenho impactado


    1. Transações concorrentes esperam o lock ser liberado

    2. Isso pode gerar lenditão em horários de pico






  2. Risco de deadlock


    1. Quando duas transações travam recursos em ordem diferentes, pode haver impasse.

    2. O banco precisa cancelar uma das transações para liberar o sistema.






  3. Acoplamento ao banco


    1. Estratégia dependente de como o banco lida com transações

    2. Pode dificultar migrações para bancos NoSQL ou cloud-native











Alternativas para sistema maiores



Em sistema com alta demanda, é possível utilizar estratégias diferentes:




  • Optimistic Locking - usa versionamento e detecta conflitos antes de salvar

  • Filas com mensageria (Kafka, RabbitMQ) - serializa operações por recurso

  • Event Sourcing e CQRS - separa leitura e escrita, com controle por eventos.






O que essa experiência me ensinou



Eu não conhecia essa abordagem a fundo antes da entrevista. Mas, graças ao avaliador que soube conduzir com clareza, paciência e provocações construtiva, saí mais preparado tecnicamente do que entrei.






Conclusão



Mais importante do que sair de uma entrvista com um “sim” ou "não”, é sair com uma certeza de que você cresceu como profissional.



Essa experiência me ensinou sobre concorrência, sobre engenharia e também sobre humildade: não saber algo é normal - o que define você é o que você faz depois disso.



Repositório do projeto → aqui 😀

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Como descobri o Pessimistic Locking e por que isso mudou minha forma de pensar sobre concorrência

Thematisch verwandte Begriffe: Como, descobri, Pessimistic, Locking · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag