LOCK#

LOCK

LOCK

LOCK — заблокировать таблицу

Синтаксис

LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]

where lockmode is one of:

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

Описание

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

Когда представление заблокировано, все отношения, указанные в запросе определения представления, также блокируются рекурсивно с тем же режимом блокировки.

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

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

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

Более подробную информацию о режимах блокировки и стратегиях блокировки можно найти в Раздел 13.3.

Параметры

name

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

Команда LOCK TABLE a, b; эквивалентна LOCK TABLE a; LOCK TABLE b;. Таблицы блокируются по одной в порядке, указанном в команде LOCK TABLE.

lockmode

Спецификация режима блокировки определяет, с какими блокировками конфликтует данная блокировка. Режимы блокировки описаны в Раздел 13.3.

Если не указан режим блокировки, то используется наиболее ограничительный режим ACCESS EXCLUSIVE.

NOWAIT

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

Примечания

LOCK TABLE ... IN ACCESS SHARE MODE требует наличия привилегий SELECT на целевую таблицу. LOCK TABLE ... IN ROW EXCLUSIVE MODE требует наличия привилегий INSERT, UPDATE, DELETE или TRUNCATE на целевую таблицу. Все остальные формы команды LOCK требуют наличия привилегий UPDATE, DELETE или TRUNCATE на уровне таблицы.

Пользователь, выполняющий блокировку представления, должен иметь соответствующие привилегии на представление. Кроме того, по умолчанию владелец представления должен иметь соответствующие привилегии на базовые отношения, в то время как пользователь, выполняющий блокировку, не требуется иметь какие-либо разрешения на базовые отношения. Однако, если у представления установлено значение true для security_invoker (см. CREATE VIEW), пользователь, выполняющий блокировку, а не владелец представления, должен иметь соответствующие привилегии на базовые отношения.

LOCK TABLE бесполезна вне блока транзакции: блокировка будет сохранена только до завершения оператора. Поэтому Tantor SE сообщает об ошибке, если LOCK используется вне блока транзакции. Используйте BEGIN и COMMIT (или ROLLBACK) для определения блока транзакции.

LOCK TABLE занимается только блокировкой на уровне таблицы, поэтому имена режимов, связанные с ROW, являются неправильными. Эти имена режимов, как правило, следует понимать как указание пользователю о намерении получить блокировку на уровне строк внутри заблокированной таблицы. Кроме того, режим ROW EXCLUSIVE является долевой блокировкой таблицы. Имейте в виду, что все режимы блокировки имеют идентичную семантику в отношении LOCK TABLE, отличаясь только правилами конфликта между режимами. Для получения информации о том, как получить фактическую блокировку на уровне строк, см. Раздел 13.3.2 и The Locking Clause в документации SELECT.

Примеры

Получите блокировку SHARE на таблице с первичным ключом перед выполнением вставок в таблицу с внешним ключом:

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 для указания уровней параллелизма в транзакциях. Tantor SE также поддерживает эту функцию; см. SET TRANSACTION для получения подробной информации.

За исключением режимов блокировки ACCESS SHARE, ACCESS EXCLUSIVE и SHARE UPDATE EXCLUSIVE, режимы блокировки Tantor SE и синтаксис LOCK TABLE совместимы с режимами блокировки, присутствующими в Oracle.