Как имитировать взаимоблокировку в PostgreSQL?
Я новичок в PostgreSQL. Я хочу имитировать тупик для этого расписания:
как имитировать взаимоблокировку в PostgreSQL? Возможно ли это вообще? Как заблокировать конкретный столбец?
EDIT:
BEGIN;
UPDATE deadlock_demonstration
SET salary1=(SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 1
FOR UPDATE)+100
WHERE worker_id=1;
SELECT pg_sleep(5);
commit;
SELECT salary2 FROM deadlock_demonstration WHERE worker_id = 1 FOR UPDATE;
на другом экране я запустил это
BEGIN;
UPDATE deadlock_demonstration
SET salary2=(SELECT salary1
FROM deadlock_demonstration
WHERE worker_id = 1
FOR UPDATE)+200
WHERE worker_id=1;
SELECT pg_sleep(5);
commit;
SELECT salary1 FROM deadlock_demonstration WHERE worker_id = 1 FOR UPDATE;
почему тупик не происходит? Можете ли вы дать предложение, что я должен изменить, чтобы стимулировать тупик?
2 ответов
- открыть два соединения параллельно, как два экземпляра
psql
или два окна запросов в pgAdmin (каждый имеет свой собственный сеанс). - запуск транзакции в каждом соединении.
BEGIN;
- запуск взаимно конфликтующих команд по очереди.
- прежде чем вы сможете зафиксировать, один из двух будет откат с исключением взаимоблокировки.
- вы можете откатить другой.
ROLLBACK;
явно замок таблицы так же просто, как:
LOCK tbl;
блокировка строк может быть выполнена с помощью:
SELECT * FROM tbl WHERE boo = 3 FOR UPDATE;
или FOR SHARE
etc. подробности в инструкции здесь.
пример
ваш добавленный пример не может взаимоблокировки. Сначала оба пытаются взять одну и ту же блокировку в одной и той же строке одной и той же таблицы. Второй будет ждать, пока первый закончит.
пример для фактического создания взаимоблокировки (строки должны существовать или блокировка не будет принято):
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 внес этот скриншот после проверки моего решения:
означает ли это, что произошел тупик?
нет. Это значит, что он говорит, Вы не можете использовать commit
в список pgsql, ясно сказано здесь.