PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie simuliert man Deadlock in PostgreSQL?

  1. Zwei Verbindungen parallel öffnen, wie zwei Instanzen von psql oder zwei Abfragefenster in pgAdmin (jedes hat seine eigene Session).
  2. Starten Sie eine Transaktion in jeder Verbindung. BEGIN;
  3. Führen Sie abwechselnd widersprüchliche Befehle aus.
  4. Bevor Sie ein Commit durchführen können, wird einer der beiden mit einer Deadlock-Ausnahme zurückgesetzt.
  5. 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: