- Otwórz dwa połączenia równolegle, jak dwie instancje
psql
lub dwa okna zapytań w pgAdmin (każde ma własną sesję). - Rozpocznij transakcję w każdym połączeniu.
BEGIN;
- Wykonuj kolejno sprzeczne polecenia.
- Zanim będziesz mógł zatwierdzić, jeden z dwóch zostanie wycofany z wyjątkiem zakleszczenia.
- Możesz wycofać drugą.
ROLLBACK;
Jawnie blokowanie tabel jest tak proste, jak:
LOCK tbl;
Blokowanie rzędów można wykonać za pomocą:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Lub FOR SHARE
itp. Szczegóły w instrukcji.
(Lub niejawnie z UPDATE
lub DELETE
.)
Przykład
Twój dodany przykład nie może się zakleszczyć. Obaj próbują najpierw przyjąć tę samą blokadę w tym samym rzędzie tej samej tabeli. Drugi będzie czekał na zakończenie pierwszego.
Przykład rzeczywistego utworzenia zakleszczenia (wiersze muszą istnieć lub blokada nie zostanie podjęta):
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!
Wynik
Użytkownik OP3388473 przesłał ten zrzut ekranu po zweryfikowaniu rozwiązania: