Блокировка таблицы.
LOCK [TABLE] [ONLY] name [ * ] [, ...] [IN lockmode MODE] [NOWAIT]
Где lockmode — один из следующих режимов:
ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
| SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
Команда LOCK TABLE получает блокировку на уровне таблицы и, при необходимости, ожидает освобождения конфликтующих блокировок. Если указан параметр NOWAIT, команда LOCK TABLE не будет ожидать получения требуемой блокировки: если она не может быть немедленно получена, команда прерывается с выдачей ошибки. После получения блокировка сохраняется до завершения текущей транзакции. Команды UNLOCK TABLE не существует; блокировка всегда освобождается в конце транзакции.
При автоматическом получении блокировок для команд, ссылающихся на таблицы, база данных YMatrix всегда использует режим блокировки с минимальными ограничениями. Команда LOCK TABLE применяется в тех случаях, когда требуется более строгая блокировка. Например, предположим, что приложение выполняет транзакцию на уровне изоляции Read Committed и должно гарантировать стабильность данных в таблице в течение всей транзакции. Для этого можно получить блокировку в режиме SHARE перед выполнением запроса. Это предотвратит параллельные изменения данных и обеспечит стабильное представление зафиксированных данных при последующих чтениях таблиц, поскольку режим блокировки SHARE конфликтует с блокировкой ROW EXCLUSIVE, которую устанавливает процесс записи, а оператор LOCK TABLE name IN SHARE MODE будет ожидать, пока все параллельные процессы, удерживающие блокировку ROW EXCLUSIVE, завершатся (зафиксируют или откатят изменения). Таким образом, после получения блокировки не останется незавершённых операций записи. Кроме того, никто не сможет начать запись, пока вы не освободите блокировку.
Чтобы достичь аналогичного результата при выполнении транзакций на уровнях изоляции REPEATABLE READ или SERIALIZABLE, оператор LOCK TABLE должен быть выполнен до любого оператора SELECT или модификации данных. При первом выполнении оператора SELECT или модификации данных в транзакциях REPEATABLE READ или SERIALIZABLE «моментальный снимок» данных фиксируется. Последующее выполнение LOCK TABLE всё ещё будет блокировать параллельные операции записи, но не гарантирует, что данные, прочитанные транзакцией, соответствуют последнему зафиксированному состоянию.
Если такие транзакции планируют изменять данные в таблице, следует использовать режим блокировки SHARE ROW EXCLUSIVE вместо режима SHARE. Это гарантирует, что одновременно выполняется только одна транзакция данного типа. В противном случае возможна взаимоблокировка: обе транзакции могут одновременно получить блокировку в режиме SHARE, а затем не смогут получить режим ROW EXCLUSIVE для выполнения своих изменений. Обратите внимание, что блокировки одной и той же транзакции никогда не конфликтуют между собой, поэтому транзакция, уже имеющая режим SHARE, может получить режим ROW EXCLUSIVE, но не сможет этого сделать, если другой процесс уже удерживает режим SHARE. Чтобы избежать взаимоблокировок, убедитесь, что все транзакции получают блокировки на одни и те же объекты в одинаковом порядке, и если к одному объекту применяются несколько режимов блокировок, транзакция должна всегда получать наиболее строгий режим в первую очередь.
name
lockmode
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.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. Ни одна команда YMatrix не устанавливает этот режим блокировки автоматически.EXCLUSIVE — Конфликтует с режимами ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE и ACCESS EXCLUSIVE. Этот режим позволяет параллельно выполнять только блокировку ACCESS SHARE, то есть параллельно с транзакцией, удерживающей блокировку, можно только читать данные из таблицы. В YMatrix этот режим автоматически устанавливается для операций UPDATE, SELECT FOR UPDATE и DELETE (более строго, чем в обычном 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) также временно устанавливает эту блокировку на таблицу с оптимизацией добавления (append-optimized table) во время обработки.Примечание: По умолчанию база данных YMatrix устанавливает блокировку EXCLUSIVE на таблицу при выполнении операций DELETE, UPDATE и SELECT FOR UPDATE над heap-таблицей. Когда включён глобальный детектор взаимоблокировок, режим блокировки для операций над heap-таблицей становится ROW EXCLUSIVE.
Для использования LOCK TABLE ... IN ACCESS SHARE MODE необходимо иметь привилегию SELECT на целевую таблицу. Все остальные формы LOCK требуют привилегий уровня таблицы: UPDATE, DELETE или TRUNCATE.
Команда LOCK TABLE бесполезна вне блоков транзакций: блокировка будет освобождена сразу после завершения выполнения оператора LOCK. Поэтому, если LOCK используется вне блока транзакции, YMatrix вернёт ошибку. Для определения блоков транзакций используйте BEGIN и END.
Команда LOCK TABLE работает только с блокировками на уровне таблиц, поэтому термины, содержащие ROW, являются условными. Эти режимы следует понимать как рекомендацию пользователю установить блокировки на уровне строк в заблокированной таблице. Кроме того, режим ROW EXCLUSIVE представляет собой разделяемую блокировку на уровне таблицы. Напоминаем, что при использовании LOCK TABLE все режимы блокировок имеют одинаковую семантику, за исключением правил конфликтов между режимами. За информацией о том, как получить реальные блокировки на уровне строк, см. раздел FOR UPDATE/FOR SHARE в документации по команде 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';
-- Do ROLLBACK if record was not returned
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 для указания уровня параллелизма транзакции. Эта возможность также поддерживается в YMatrix.
За исключением режимов ACCESS SHARE, ACCESS EXCLUSIVE и SHARE UPDATE EXCLUSIVE, режимы блокировок и синтаксис команды LOCK TABLE в YMatrix совместимы с Oracle.