postgres тупик без явной блокировки

Я использую PostgreSQL 9.2 и не использую явную блокировку нигде, ни LOCK заявление ни SELECT ... FOR UPDATE, Однако недавно я получил ERROR: 40P01: deadlock detected, Запрос, в котором была обнаружена взаимоблокировка, помещается в блок транзакции. Во всяком случае, как это получается?

2 ответа

Решение

Вам не нужно никаких явных LOCK зайти в тупик. Вот очень простая демонстрация с нуля только с ВСТАВКАМИ:

create table a(i int primary key);
create table b(i int primary key);

Сессия № 1 делает:

begin;
insert into a values(1);

Затем сессия № 2 делает:

begin;
insert into b values(1);
insert into a values(1);
-- here it goes into waiting for session #1 to finish its transaction

Затем сессия № 1 делает:

insert into b values(1);

И тогда возникает тупик:

ОШИБКА: обнаружен тупик
ДЕТАЛИ: Процесс 9571 ожидает ShareLock для транзакции 4150; заблокирован процессом 9501.
Процесс 9501 ожидает ShareLock для транзакции 4149; заблокирован процессом 9571.
СОВЕТ: см. Журнал сервера для деталей запроса.

То же самое может случиться с простыми ОБНОВЛЕНИЯМИ или комбинацией ОБНОВЛЕНИЙ и ВСТАВКИ. Эти операции принимают неявные блокировки, и если они происходят в разных сеансах в разных порядках, они могут зайти в тупик.

Я бы сначала заподозрил хеш-индексы.

  • Переключить любой hash Индексам нужно B-tree
  • использование Serializable уровень изоляции, если это кажется целесообразным.
Другие вопросы по тегам