- Åbn to forbindelser parallelt, som to forekomster af
psql
eller to forespørgselsvinduer i pgAdmin (hver har sin egen session). - Start en transaktion i hver forbindelse.
BEGIN;
- Kør indbyrdes modstridende kommandoer på skift.
- Før du kan forpligte dig, vil en af de to blive rullet tilbage med en deadlock undtagelse.
- Du ønsker måske at rulle den anden tilbage.
ROLLBACK;
Eksplicit låsning af tabeller er så simpelt som:
LOCK tbl;
Låsning af rækker kan udføres med:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Eller FOR SHARE
osv. Detaljer i manualen.
(Eller implicit med UPDATE
eller DELETE
.)
Eksempel
Dit tilføjede eksempel kan ikke gå i stå. Begge prøver at tage den samme lås på den samme række af det samme bord først. Den anden vil vente på, at den første er færdig.
Eksempel på rent faktisk at producere en deadlock (rækker skal eksistere, ellers vil ingen lås blive taget):
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!
Resultat
OP-brugeren3388473 bidrog med dette skærmbillede efter at have verificeret løsningen: