- Öppna två anslutningar parallellt, som två instanser av
psql
eller två frågefönster i pgAdmin (var och en har sin egen session). - Starta en transaktion i varje anslutning.
BEGIN;
- Kör ömsesidigt motstridiga kommandon i tur och ordning.
- Innan du kan förbinda dig kommer en av de två att återställas med ett dödläge undantag.
- Du kanske vill återställa den andra.
ROLLBACK;
Explicit låsa tabeller är så enkelt som:
LOCK tbl;
Låsning av rader kan göras med:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Eller FOR SHARE
etc. Detaljer i manualen.
(Eller implicit med UPDATE
eller DELETE
.)
Exempel
Ditt tillagda exempel kan inte låsa sig. Båda försöker ta samma lås på samma rad på samma bord först. Den andra väntar på att den första är klar.
Exempel för att faktiskt skapa ett dödläge (rader måste finnas annars kommer inget lås att tas):
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-användaren3388473 bidrog med den här skärmdumpen efter att ha verifierat lösningen: