Из тестов, которые мы провели в PostgreSQL, кажется, что непредоставленная эксклюзивная блокировка доступа к таблице блокирует блокировку общего доступа. Ниже описан тест, который мы выполнили.
Сессия 1:
begin;
select * from users where id = 1;
Примечание. Транзакция намеренно оставлена открытой для проверки.
Сессия 2:
alter table users add column foo boolean;
Примечание: Этот оператор заблокирован оператором в сеансе 1. Эксклюзивная блокировка доступа еще не предоставлена.
Сессия 3:
select * from users where id = 2;
Последний оператор в сеансе 3 заблокирован.
Как это блокируется, когда монопольная блокировка доступа из оператора alter еще не предоставлена (поскольку она заблокирована сеансом 1)? Есть ли что-то, чего нам не хватает?
В документации описано, что:
Один серверный процесс блокирует другой, если он либо удерживает блокировку, конфликтующую с запросом на блокировку заблокированного процесса (жесткая блокировка), либо ожидает блокировку, которая конфликтует с запросом на блокировку заблокированного процесса, и стоит перед ним в очереди ожидания (мягкая блокировка). блокировать).
Таким образом, блокировки, которые не предоставлены, ставятся в очередь, и вы не можете перейти в очередь перед процессом с конфликтующим запросом на блокировку. Это сделано для того, чтобы ни один процесс не мог быть заблокирован навсегда (если только блокировка транзакций не будет длиться вечно).