Deadlock (Verklemmung)
Ein Deadlock liegt vor, wenn zwei oder mehr Transaktionen zyklisch aufeinander warten. T1 hält eine Sperre auf A und benötigt B, während T2 B hält und A benötigt. Ohne Eingriff wartet beides ewig. Voraussetzung ist typischerweise das strenge 2PL-Protokoll, das Sperren bis EOT hält. Deadlocks sind ein Konsistenzsicherungs-Problem und müssen vom DBMS entdeckt und aufgelöst werden.
Zwei Transaktionen, zwei Sperren, kreuzweise gefordert = Deadlock.
Wait-for-Graph (Wartegraph)
Der Wartegraph ist ein gerichteter Graph mit Knoten für Transaktionen und Kanten Ti -> Tj, wenn Ti auf eine Sperre wartet, die Tj hält. Er wird aus der Lock-Tabelle des DBMS gebildet. Enthält der Graph einen Zyklus, liegt ein Deadlock vor. Zyklenerkennung erfolgt per Tiefensuche. Zur Auflösung wird eine Transaktion aus dem Zyklus ausgewählt, zurückgesetzt (abort + R1-Recovery) und dadurch können beide Zyklen mit einem einzigen Opfer aufgebrochen werden, wenn dieses gemeinsame Knoten liegt.
Zyklus im Wartegraph = Deadlock, Opfer bricht den Kreis.
Preclaiming
Beim Preclaiming muss jede Transaktion vor Ausführung ihrer Operationen ALLE benötigten Sperren auf einmal erwerben. Erst wenn alle Sperren vorhanden sind, startet die eigentliche Arbeit. In Verbindung mit strengem 2PL bedeutet dies, dass die Sperrmenge sofort auf Maximum steht und bis EOT gehalten wird. Dadurch können niemals zwei Transaktionen wechselseitig auf Sperren warten. Nachteil: geringere Parallelität und man muss im Voraus wissen, welche Objekte gebraucht werden.
Alles vorab sperren, dann arbeiten - keine Kreise möglich.
Wound-Wait (Junge warten auf Alte)
Zeitstempel-basierte Vermeidung. Jede Transaktion bekommt beim Start einen eindeutigen Zeitstempel. Ältere TAs haben kleinere Stempel. Fordert T1 eine Sperre an, die T2 hält: Ist T1 älter als T2, wird T2 abgebrochen (wound) und zurückgesetzt, T1 läuft weiter. Ist T1 jünger, wartet T1 regulär. Wound-Wait bevorzugt ältere Transaktionen, indem sie jüngere verdrängen.
Alte darf junge verletzen - junge warten geduldig.
Wait-Die (Alte warten auf Junge)
Zweite Zeitstempel-Strategie. Fordert T1 eine Sperre, die T2 hält: Ist T1 älter als T2, wartet T1 auf die Freigabe. Ist T1 jünger, wird T1 abgebrochen (die) und mit gleichem Zeitstempel neu gestartet. Bei Wait-Die dürfen nur ältere Transaktionen warten, jüngere sterben und werden neu gestartet. Beide Strategien vermeiden Zyklen, weil die Warterichtung immer nur in eine Zeitstempel-Richtung geht.
Alte warten geduldig, junge sterben und starten neu.
Erkennung vs. Vermeidung
Zwei Grundansätze: Deadlock-Erkennung (detection) lässt Deadlocks entstehen und löst sie über den Wartegraph auf. Deadlock-Vermeidung (avoidance/prevention) verhindert Deadlocks strukturell, z.B. durch Preclaiming oder Zeitstempel. Erkennung erlaubt höhere Parallelität, kostet aber Zyklensuche. Vermeidung ist proaktiv, reduziert aber Nebenläufigkeit oder erzeugt unnötige Rollbacks.
Erkennen und auflösen oder vermeiden bevor es passiert.
Strenges 2PL als Voraussetzung
Deadlocks sind ein typisches Problem des strengen Zwei-Phasen-Sperrprotokolls (S2PL). Dort werden alle Sperren bis zum EOT gehalten, damit kaskadierendes Rücksetzen ausgeschlossen ist. Genau dieses lange Halten der Sperren macht aber Zyklen im Wartegraph möglich. Ohne 2PL wären Deadlocks im klassischen Sinn nicht das Hauptproblem, dafür aber Inkonsistenzen wie Dirty Read und Lost Update.
S2PL sichert Konsistenz, öffnet aber Tür für Deadlocks.
Auflösung durch Rollback (Opferwahl)
Wird ein Zyklus erkannt, wählt das DBMS ein Opfer im Zyklus aus (häufig die jüngste, die mit wenigsten Sperren oder die mit geringsten Kosten). Das Opfer erhält abort und wird per R1-Recovery zurückgesetzt. Die freigewordenen Sperren erlauben den anderen TAs, weiterzulaufen. Liegt ein Knoten in mehreren Zyklen, kann sein Rollback mehrere Verklemmungen gleichzeitig lösen.
Ein Opfer, ein Rollback - der Zyklus zerfällt.