- Zwei Verbindungen parallel öffnen, wie zwei Instanzen von
psql
oder zwei Abfragefenster in pgAdmin (jedes hat seine eigene Session). - Starten Sie eine Transaktion in jeder Verbindung.
BEGIN;
- Führen Sie abwechselnd widersprüchliche Befehle aus.
- Bevor Sie ein Commit durchführen können, wird einer der beiden mit einer Deadlock-Ausnahme zurückgesetzt.
- Möglicherweise möchten Sie den anderen zurücksetzen.
ROLLBACK;
Explizit Sperren von Tabellen ist so einfach wie:
LOCK tbl;
Das Sperren von Zeilen kann erfolgen mit:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Oder FOR SHARE
usw. Details im Handbuch.
(Oder implizit mit UPDATE
oder DELETE
.)
Beispiel
Ihr hinzugefügtes Beispiel kann nicht blockiert werden. Beide versuchen zuerst, dieselbe Sperre für dieselbe Zeile derselben Tabelle zu nehmen. Der zweite wartet, bis der erste fertig ist.
Beispiel, um tatsächlich einen Deadlock zu erzeugen (Zeilen müssen vorhanden sein oder es wird kein Lock genommen):
Transaction 1 Transaction 2
BEGIN;
BEGIN;
SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 1
FOR UPDATE;
SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 2
FOR UPDATE;
UPDATE deadlock_demonstration
SET salary1 = 100
WHERE worker_id = 2;
UPDATE deadlock_demonstration
SET salary1 = 100
WHERE worker_id = 1;
--> ... 💣 deadlock!
Ergebnis
Der OP-Benutzer3388473 hat diesen Screenshot beigesteuert, nachdem er die Lösung überprüft hat: