Deadlocks: Erkennung und Vermeidung
Verstehen Sie, wie Deadlocks entstehen, wie Postgres sie erkennt, und entwerfen Sie Regeln für die Sperrreihenfolge, die sie verhindern.
Deadlocks: Erkennung und Vermeidung ist eine kostenlose SQL Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des SQL Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der SQL Academy-Kurs umfasst insgesamt 4 Lektionen.
Was ist ein Deadlock?
Zwei Transaktionen halten jeweils eine Sperre, die die andere benötigt — keine kann fortfahren. Die Datenbank erkennt den Zyklus und bricht eine der Transaktionen ab.
Ein klassischer Deadlock
Tx A sperrt Zeile 1, Tx B sperrt Zeile 2. A fordert Zeile 2 an, B fordert Zeile 1 an. Stillstand.
-- Tx A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- waiting for B...
-- Tx B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 2;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
-- waiting for A...
-- ERROR: deadlock detectedPostgreSQL erkennt Deadlocks
Bei jedem deadlock_timeout (standardmäßig 1 Sekunde) prüft PostgreSQL auf Sperrzyklen. Wird einer gefunden, bricht PostgreSQL eine Transaktion mit dem Fehlercode 40P01 ab.
ERROR: deadlock detected
DETAIL: Process 1234 waits for ShareLock on transaction 5678 ...Regel für die Sperrenreihenfolge
Die Lösung: Erwerben Sie Sperren in allen Codepfaden immer in derselben Reihenfolge.
-- Always update the lower id first:
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(:from, :to);
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(:from, :to);Deadlocks bei stark umkämpften Zeilen
Schnelle Aktualisierungen derselben stark umkämpften Zeilen führen häufig zu Wartezeiten auf Sperren, nicht zu Deadlocks. Verwenden Sie Queues, partitionieren Sie die umkämpfte Zeile oder serialisieren Sie Aktualisierungen im Anwendungscode.
FOR UPDATE sperrt gelesene Zeilen
Erwerben Sie bereits beim Lesen Schreibsperren, um spätere Überraschungen zu vermeiden:
BEGIN;
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
-- both rows locked in id order
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;Gesperrte Zeilen überspringen
Für Queue-Tabellen, das Muster "beliebige verfügbare Zeile holen":
SELECT * FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;
-- skips rows other workers have lockedNOWAIT
Sofort fehlschlagen, statt zu warten:
SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR: could not obtain lock on row in relation "accounts"Deadlocks diagnostizieren
Erhöhen Sie log_lock_waits und protokollieren Sie den Deadlock-Kontext. Der Protokolleintrag zeigt beide Transaktionen und ihre Abfragen.
Wiederholungsschleife der Anwendung
Deadlocks sind behebbar — wiederholen Sie die abgebrochene Transaktion:
for (let attempt = 0; attempt < 3; attempt++) {
try {
await runTransaction();
break;
} catch (e) {
if (e.code === '40P01') continue; // deadlock
throw e;
}
}Den Umfang von Sperren reduzieren
Verkürzen Sie Transaktionen — jede betroffene Zeile bleibt bis zum COMMIT gesperrt. Führen Sie innerhalb einer Transaktion keine HTTP-Aufrufe oder langwierigen Berechnungen aus.
Fremdschlüssel indizieren, um eine Eskalation von Sperren zu vermeiden
Wenn Sie ein übergeordnetes Element löschen, wird jede untergeordnete Zeile geprüft. Ohne FK-Index bedeutet das einen vollständigen Tabellenscan UND Zeilensperren. Erstellen Sie für jede FK-Spalte einen Index.
Zusammenfassung
Deadlocks treten auf — entwickeln Sie Ihr System so, dass sie möglichst selten entstehen.
- Erwerben Sie Sperren in einer einheitlichen Reihenfolge
- Verwenden Sie FOR UPDATE frühzeitig, um Ihre Absicht zu erklären
- SKIP LOCKED für Queues
- Wiederholen Sie Vorgänge bei Deadlock-Fehlern (40P01)
- Halten Sie Transaktionen kurz
Kurzer Check
Welches Designprinzip verhindert Deadlocks am zuverlässigsten?
Häufig gestellte Fragen
Ist die Lektion „Deadlocks: Erkennung und Vermeidung“ kostenlos?
Ja — der vollständige Text von „Deadlocks: Erkennung und Vermeidung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des SQL Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der SQL Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Deadlocks: Erkennung und Vermeidung“?
Verstehen Sie, wie Deadlocks entstehen, wie Postgres sie erkennt, und entwerfen Sie Regeln für die Sperrreihenfolge, die sie verhindern. Du übst SQL Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um SQL Academy zu starten?
Keine Vorkenntnisse erforderlich. SQL Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Deadlocks: Erkennung und Vermeidung“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser SQL Academy-Lektion Code schreiben und ausführen?
Ja. Jede SQL Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- ACID-Eigenschaften und Anomalien
- Isolationsstufen: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
- Deadlocks: Erkennung und Vermeidung
- Optimistisches vs. pessimistisches Sperren