- Otevřete dvě připojení paralelně, například dvě instance
psql
nebo dvě okna dotazů v pgAdmin (každé má svou vlastní relaci). - Zahajte transakci v každém připojení.
BEGIN;
- Spouštějte vzájemně konfliktní příkazy střídavě.
- Než budete moci provést potvrzení, jeden z nich bude vrácen zpět s výjimkou uváznutí.
- Možná budete chtít vrátit toho druhého zpět.
ROLLBACK;
Explicitně uzamykání tabulek je stejně jednoduchý jako:
LOCK tbl;
Uzamčení řádků lze provést pomocí:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Nebo FOR SHARE
atd. Podrobnosti v příručce.
(Nebo implicitně pomocí UPDATE
nebo DELETE
.)
Příklad
Váš přidaný příklad nemůže uváznout. Oba se nejprve pokusí vzít stejný zámek na stejném řádku stejné tabulky. Druhý počká na dokončení prvního.
Příklad skutečného vytvoření uváznutí (řádky musí existovat, jinak se zámek nepřevezme):
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!
Výsledek
Uživatel OP user3388473 přispěl tímto snímkem obrazovky po ověření řešení: