Appearance
Pessimistic Locking β
Zusammenfassung β
Pessimistic Locking sperrt eine Datenbankzeile sofort beim Lesen, um Race Conditions zu verhindern. Es garantiert, dass nur ein Thread/Request die Daten modifizieren kann.
Kernkonzept β
Pessimistic Locking geht davon aus, dass Konflikte hΓ€ufig vorkommen und sperrt Ressourcen prΓ€ventiv.
Die Sperre wird beim SELECT-Statement gesetzt (z.B. mit FOR UPDATE). Andere Transaktionen warten, bis die Sperre freigegeben wird. Dies verhindert Dirty Reads und Lost Updates vollstΓ€ndig.
In Spring Data JPA wird es ΓΌber @Lock-Annotation und LockModeType gesteuert. Die Datenbank handhΓ€lt die technische Sperrung, nicht die Applikation.
Code-Beispiel β
java
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {
// Pessimistic Read Lock β andere kΓΆnnen lesen, aber nicht schreiben
@Lock(LockModeType.PESSIMISTIC_READ)
@Query("SELECT a FROM Account a WHERE a.id = :id")
Optional<Account> findByIdWithReadLock(@Param("id") Long id);
// Pessimistic Write Lock β exklusive Sperre
@Lock(LockModeType.PESSIMISTIC_WRITE)
Account findByIdForUpdate(Long id);
}
// Service-Nutzung
@Service
public class TransferService {
@Transactional
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
// Sperre wird sofort gesetzt β andere Threads warten
Account from = accountRepo.findByIdForUpdate(fromId);
Account to = accountRepo.findByIdForUpdate(toId);
from.withdraw(amount);
to.deposit(amount);
// Sperre wird beim Commit/Ende der Transaktion freigegeben
}
}Wichtige Punkte β
- LockModeType.PESSIMISTIC_WRITE: Exklusive Sperre, niemand darf lesen/schreiben
- LockModeType.PESSIMISTIC_READ: Shared Lock, mehrere dΓΌrfen lesen, aber keiner schreiben
- Timeout-Handling:
javax.persistence.lock.timeoutProperty fΓΌr Lock-Wartezeit setzen - Transaktion erforderlich: Funktioniert nur innerhalb einer aktiven
@Transactional-Methode - Performance-Tradeoff: Sperren fΓΌhren zu Wartezeiten und kΓΆnnen Deadlocks verursachen
Klassische Fragen β
Wann sollte man Pessimistic statt Optimistic Locking nutzen? β
Bei hohen Konfliktraten (viele parallele Schreibzugriffe auf gleiche Daten) und kritischen Operationen (Geldtransfers, Inventory-Management). Optimistic ist besser bei niedriger Konfliktrate.
Was ist der Unterschied zu Optimistic Locking? β
Optimistic Locking nutzt Versionsnummern und erkennt Konflikte erst beim Update. Pessimistic sperrt sofort prΓ€ventiv. Pessimistic ist sicherer, aber langsamer.
Kann ein Deadlock entstehen? β
Ja! Wenn Thread A Zeile 1 sperrt und auf Zeile 2 wartet, wΓ€hrend Thread B Zeile 2 sperrt und auf Zeile 1 wartet. Vermeidung: Konsistente Sperr-Reihenfolge oder Timeout.
Funktioniert Pessimistic Locking ΓΌber mehrere Datenbanken? β
Nein, die Sperre ist auf eine DB-Instanz begrenzt. FΓΌr verteilte Systeme brauchst du externe Lock-Manager (Redis, Consul, Zookeeper).
Wusstest du schon? β
Die FOR UPDATE-Klausel stammt aus ANSI-SQL und ist in PostgreSQL, MySQL und Oracle identisch implementiert β aber DB2 nutzt FOR UPDATE WITH RS und SQLite unterstΓΌtzt es gar nicht! π―