- Open twee parallelle verbindingen, zoals twee instanties van
psql
of twee queryvensters in pgAdmin (elk heeft zijn eigen sessie). - Start een transactie in elke verbinding.
BEGIN;
- Voer om beurten tegenstrijdige opdrachten uit.
- Voordat je kunt committen, wordt een van de twee teruggedraaid met een deadlock-uitzondering.
- Misschien wil je de andere terugdraaien.
ROLLBACK;
Expliciet tabellen vergrendelen is zo simpel als:
LOCK tbl;
Het vergrendelen van rijen kan met:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Of FOR SHARE
etc. Details in de handleiding.
(Of impliciet met UPDATE
of DELETE
.)
Voorbeeld
Uw toegevoegde voorbeeld kan niet vastlopen. Beiden proberen eerst hetzelfde slot op dezelfde rij van dezelfde tafel te pakken. De tweede wacht tot de eerste klaar is.
Voorbeeld om daadwerkelijk een deadlock te produceren (rijen moeten bestaan of er wordt geen lock gebruikt):
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!
Resultaat
De OP-gebruiker 3388473 heeft deze screenshot bijgedragen na het verifiëren van de oplossing: