Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

LOCK

Блокирует таблицу.

Синтаксис

LOCK [TABLE] [ONLY] <table_name> [ * ] [, ...] [IN <lockmode> MODE] [NOWAIT] [MASTER ONLY]

где lockmode может быть:

  ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
| SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

Описание

LOCK TABLE получает блокировку на уровне таблицы, ожидая при необходимости снятия конфликтующих блокировок. Если указан NOWAIT, LOCK TABLE не ждет получения нужной блокировки: если блокировку невозможно получить немедленно, команда прерывается и выдается ошибка. Как только блокировка получена, она удерживается до завершения текущей транзакции. Команды UNLOCK TABLE нет; блокировки всегда снимаются в конце транзакции.

При автоматическом получении блокировок для команд, обращающихся к таблицам, Greengage DB всегда использует наименее ограничивающий режим блокировки. Команда LOCK TABLE предназначена для случаев, когда может потребоваться более строгая блокировка. Например, предположим, что приложение выполняет транзакцию на уровне изоляции READ COMMITTED и должно гарантировать, что данные в таблице останутся неизменными на протяжении всей транзакции. Для этого можно получить для таблицы блокировку в режиме SHARE перед обращением к ней. Это предотвратит параллельные изменения данных и обеспечит стабильное представление зафиксированных данных при последующем чтении таблицы, поскольку режим блокировки SHARE конфликтует с блокировкой ROW EXCLUSIVE, запрашиваемой при записи, и LOCK TABLE <table_name> IN SHARE MODE будет ждать, пока параллельные транзакции с блокировкой ROW EXCLUSIVE не будут зафиксированы или отменены. Таким образом, в момент получения блокировки не останется незафиксированных операций записи; более того, ни одна из них не может начаться, пока блокировка не будет снята.

Для достижения аналогичного эффекта при выполнении транзакции на уровне изоляции REPEATABLE READ или SERIALIZABLE необходимо выполнить LOCK TABLE перед выполнением SELECT или команды изменения данных. Состояние данных для транзакции REPEATABLE READ или SERIALIZABLE будет "заморожено" на момент, когда начнет выполняться этот запрос. Команда LOCK TABLE, выполняемая в транзакции позже, также будет исключать параллельную запись — но не гарантирует, что считываемые транзакцией данные будут соответствовать последним зафиксированным значениям.

Если в транзакции такого типа требуется изменить данные в таблице, для нее следует использовать режим блокировки SHARE ROW EXCLUSIVE вместо SHARE. Это гарантирует, что в один момент времени будет выполняться только одна транзакция этого типа. Без этого ограничения возможна взаимоблокировка: две транзакции могут одновременно получить блокировки SHARE и не смогут получить блокировку ROW EXCLUSIVE, чтобы фактически выполнить изменения. Обратите внимание, что собственные блокировки транзакции никогда не конфликтуют, поэтому транзакция может получить блокировку ROW EXCLUSIVE, если она владеет блокировкой SHARE, но не тогда, когда другая транзакция удерживает блокировку SHARE. Чтобы избежать взаимоблокировок, убедитесь, что все транзакции получают блокировки одних и тех же объектов в одном и том же порядке, и если для одного объекта задействовано несколько блокировок в разных режимах, то транзакции всегда должны сначала получать наиболее строгую блокировку.

Параметры

Параметр Описание

table_name

Имя (опционально указанное со схемой) существующей таблицы, которую необходимо заблокировать. Если перед именем таблицы указано ONLY, блокируется только эта таблица. Если ONLY не указано, блокируется таблица и все ее дочерние таблицы (если таковые имеются). После имени таблицы опционально можно указать *, чтобы явно обозначить включение дочерних таблиц.

Если указано несколько таблиц, таблицы блокируются по одной в порядке, указанном в команде LOCK TABLE

lockmode

Режим блокировки определяет, с какими блокировками будет конфликтовать данная блокировка. Если режим блокировки не указан, используется наиболее строгий режим — ACCESS EXCLUSIVE. Доступны следующие режимы блокировки:

  • ACCESS SHARE — конфликтует только с режимом блокировки ACCESS EXCLUSIVE. Команда SELECT получает такую блокировку для таблиц, на которые она ссылается. Любой запрос, который только читает таблицу и не изменяет ее, получает этот режим блокировки.

  • ROW SHARE — конфликтует с режимами блокировки EXCLUSIVE и ACCESS EXCLUSIVE. Команда SELECT FOR SHARE автоматически получает эту блокировку для целевых таблиц (в дополнение к блокировкам ACCESS SHARE для любых других таблиц, задействованных без указания FOR SHARE).

  • ROW EXCLUSIVE — конфликтует с режимами блокировки SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE и ACCESS EXCLUSIVE. Команды INSERT и COPY автоматически получают такую блокировку для целевой таблицы (в дополнение к блокировкам ACCESS SHARE для любых других задействованных таблиц).

  • SHARE UPDATE EXCLUSIVE — конфликтует с режимами блокировки SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE и ACCESS EXCLUSIVE. Этот режим защищает таблицу от одновременного изменения схемы и выполнения команды VACUUM. Запрашивается командами VACUUM (без FULL) для heap-таблиц и ANALYZE.

  • SHARE — конфликтует с режимами блокировки ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE и ACCESS EXCLUSIVE. Этот режим защищает таблицу от одновременных изменений данных. Автоматически устанавливается командой CREATE INDEX.

  • SHARE ROW EXCLUSIVE — конфликтует с режимами блокировки ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE и ACCESS EXCLUSIVE. Этот режим блокировки не устанавливается автоматически ни одной командой Greengage DB.

  • EXCLUSIVE — конфликтует с режимами блокировки ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE и ACCESS EXCLUSIVE. Этот режим совместим только с блокировкой ACCESS SHARE, то есть параллельно с транзакцией, получившей этот режим блокировки, могут выполняться только операции чтения из таблицы. Этот режим блокировки автоматически устанавливается для UPDATE, SELECT FOR UPDATE и DELETE в Greengage DB (что обеспечивает более строгую блокировку, чем в обычном PostgreSQL).

  • ACCESS EXCLUSIVE — конфликтует со всеми режимами блокировки (ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE и ACCESS EXCLUSIVE). Этот режим гарантирует, что кроме транзакции, получившей эту блокировку, никакая другая транзакция не может обращаться к таблице каким-либо образом. Автоматически устанавливается командами ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER и VACUUM FULL. Это режим блокировки по умолчанию для операторов LOCK TABLE, если явно не выбран другой режим. Эта блокировка также кратковременно устанавливается командой VACUUM (без FULL) в таблицах, оптимизированных для добавления данных, во время обработки.

ПРИМЕЧАНИЕ

По умолчанию Greengage DB устанавливает более строгую блокировку EXCLUSIVE (в отличие от ROW EXCLUSIVE в PostgreSQL) для операций UPDATE, DELETE и SELECT …​ FOR UPDATE в heap-таблицах. При включении Global Deadlock Detector для операций UPDATE и DELETE в heap-таблицах устанавливается режим блокировки ROW EXCLUSIVE. Greengage DB всегда удерживает блокировку на уровне таблицы при использовании операторов SELECT …​ FOR UPDATE.

NOWAIT

Указывает, что команда LOCK TABLE не должна ждать освобождения конфликтующих блокировок: если указанная блокировка не может быть получена немедленно без ожидания, транзакция прерывается

MASTER ONLY

Указывает, что при выполнении команды LOCK TABLE Greengage DB будет блокировать таблицы только на мастере, а не на мастере и всех сегментах. Это особенно полезно для операций, связанных только с метаданными

Примечания

Для выполнения команды LOCK TABLE …​ IN ACCESS SHARE MODE требуются права SELECT на целевую таблицу. Для всех остальных типов команды LOCK требуются права UPDATE, DELETE или TRUNCATE на уровне таблицы.

Команда LOCK TABLE бесполезна вне блока транзакции: блокировка будет сохраняться только до завершения операции. Поэтому Greengage DB сообщает об ошибке при попытке применить LOCK вне блока транзакции. Используйте BEGIN и END для определения блока транзакции.

LOCK TABLE может устанавливать только блокировки на уровне таблицы, поэтому имена режимов, включающие ROW, не совсем корректны. Эти названия режимов, как правило, следует понимать как указание на намерение пользователя получить блокировки на уровне строк в заблокированной таблице. Кроме того, учтите, что в режиме ROW EXCLUSIVE устанавливается разделяемая блокировка таблицы. Следует помнить, что все режимы блокировки имеют одинаковую семантику в отношении LOCK TABLE, отличаясь только правилами конфликта режимов. За информацией о том, как получить фактическую блокировку на уровне строки, обратитесь к разделу Выражения блокировки статьи SELECT.

Примеры

Получение блокировки SHARE для таблицы films при добавлении записей в таблицу films_user_comments:

BEGIN WORK;

LOCK TABLE films IN SHARE MODE;

SELECT id
FROM films
WHERE name = 'Star Wars: Episode I - The Phantom Menace';

-- Если запись не будет возвращена, выполнится откат транзакции
INSERT INTO films_user_comments
VALUES (_id_, 'GREAT! I was waiting for it for so long!');

COMMIT WORK;

Получение блокировки SHARE ROW EXCLUSIVE для таблицы перед выполнением операции удаления:

BEGIN WORK;

LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;

DELETE
FROM films_user_comments
WHERE id IN
      (SELECT id FROM films WHERE rating < 5);

DELETE
FROM films
WHERE rating < 5;

COMMIT WORK;

Совместимость

В стандарте SQL отсутствует команда LOCK TABLE, вместо нее используется команда SET TRANSACTION для указания уровней параллельного доступа к транзакциям. Greengage DB также поддерживает эту команду.

За исключением режимов блокировки ACCESS SHARE, ACCESS EXCLUSIVE и SHARE UPDATE EXCLUSIVE, режимы блокировки в Greengage DB и синтаксис LOCK TABLE совместимы с режимами, присутствующими в СУБД Oracle.