- Отворете две връзки паралелно, като две копия на
psql
или два прозореца за заявки в pgAdmin (всеки има своя собствена сесия). - Започнете транзакция във всяка връзка.
BEGIN;
- Изпълнявайте взаимно противоречащи си команди на свой ред.
- Преди да можете да се ангажирате, едно от двете ще бъде върнато назад с изключение от блокиране.
- Може да искате да върнете другия.
ROLLBACK;
Изрично заключване на таблици е толкова просто като:
LOCK tbl;
Заключването на редове може да се направи с:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
Или FOR SHARE
и т.н. Подробности в ръководството.
(Или имплицитно с UPDATE
или DELETE
.)
Пример
Вашият добавен пример не може да блокира. И двамата се опитват първо да вземат едно и също заключване на един и същи ред на същата таблица. Вторият ще изчака първия да завърши.
Пример за действително създаване на блокиране (трябва да съществуват редове или няма да бъде взето заключване):
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!
Резултат
OP user3388473 предостави тази екранна снимка, след като провери решението: