BEGIN/COMMIT/ROLLBACK
LOCK TABLES/UNLOCK TABLES
SET TRANSACTIO
NBuy this Reference Manual in softcover from Barnes & Noble!
LOCK TABLES/UNLOCK TABLES
LOCK TABLES tbl_name [AS alias] {READ | [READ LOCAL] | [LOW_PRIORITY] WRITE} [, tbl_name {READ | [LOW_PRIORITY] WRITE} ...] ... UNLOCK TABLES
Команда LOCK TABLES
блокирует указанные в ней таблицы для данного потока. Команда UNLOCK TABLES
снимает любые блокировки, удерживаемые данным потоком. Все таблицы, заблокированные текущим потоком, автоматически разблокируются при появлении в потоке иной команды LOCK TABLES
или при прекращении соединения с сервером.
Чтобы использовать команду LOCK TABLES
в MySQL 4.0.2, необходимо иметь глобальные привилегии LOCK TABLES
и SELECT
для заданных таблиц. В MySQL 3.23 для этого необходимы привилегии SELECT
, INSERT
, DELETE
и UPDATE
для рассматриваемых таблиц.
Основные преимущества использования команды LOCK TABLES
состоят в том, что она позволяет осуществлять эмуляцию транзакций или получить более высокую скорость при обновлении таблиц. Ниже это разъясняется более подробно.
Если в потоке возникает блокировка операции READ
для некоторой таблицы, то только этот поток (и все другие потоки) могут читать из данной таблицы. Если для некоторой таблицы в потоке существует блокировка WRITE
, тогда только поток, содержащий блокировку, может осуществлять операции READ
и WRITE
на данной таблице. Остальные потоки блокируются.
Различие между READ LOCAL
и READ
состоит в том, что READ LOCAL
позволяет выполнять неконфликтующие команды INSERT
во время существования блокировки. Однако эту команду нельзя использовать для работы с файлами базы данных вне сервера MySQL во время данной блокировки.
При использовании команды LOCK TABLES
необходимо блокировать все таблицы, которые предполагается использовать в последующих запросах, употребляя при этом те же самые псевдонимы, которые будут в запросах! Если таблица упоминается в запросе несколько раз (с псевдонимами), необходимо заблокировать каждый псевдоним!
Блокировка WRITE
обычно имеет более высокий приоритет, чем блокировка READ
, чтобы гарантировать, что изменения обрабатываются так быстро, как возможно. Это означает, что если один поток получает блокировку READ
и затем иной поток запрашивает блокировку WRITE
, последующие запросы на блокировку READ
будут ожидать, пока поток WRITE
не получит блокировку и не снимет ее. Можно использовать блокировки LOW_PRIORITY WRITE
, позволяющие другим потокам получать блокировки READ
в то время, как основной поток находится в состоянии ожидания блокировки WRITE
. Блокировки LOW_PRIORITY
WRITE
могут быть использованы только если есть уверенность, что в конечном итоге будет период времени, когда ни один из потоков не будет иметь блокировки READ
.
Команда LOCK TABLES
работает следующим образом:
WRITE
ставится перед блокировкой READ
, если таблицы блокируются с блокировками READ
и WRITE
.Описанный порядок действий гарантирует, что блокирование таблицы не создает тупиковой ситуации. Однако есть и другие вещи, о которых необходимо отдавать себе отчет при работе по описанной схеме:
Использование для таблицы блокировки LOW_PRIORITY_WRITE
всего лишь означает, что MySQL будет выполнять данную конкретную блокировку, пока не появится поток, запрашивающий блокировку READ
. Если поток получил блокировку WRITE
и находится в ожидании блокировки следующей таблицы из списка блокируемых таблиц, то все остальные потоки будут ожидать, пока блокировка WRITE
не будет снята. Если это представляет серьезную проблему для вашего приложения, то следует подумать о преобразовании имеющихся таблиц в таблицы иного вида, поддерживающие транзакции.
Поток, ожидающий блокировку таблицы, можно безопасно уничтожить с помощью команды KILL
. See section 4.5.5 Синтаксис команды KILL
.
Учтите, что нельзя блокировать любые таблицы, используемые совместно с оператором INSERT DELAYED
, поскольку в этом случае команда INSERT
выполняется как отдельный поток.
Обычно нет необходимости блокировать таблицы, поскольку все единичные команды UPDATE
являются неделимыми; никакой другой поток не может взаимодействовать с какой-либо SQL-командой, выполняемой в данное время. Однако в некоторых случаях предпочтительно тем или иным образом осуществлять блокировку таблиц:
READ
или прочитать таблицу с блокировкой WRITE
. При блокировке LOCK TABLES
операции выполняются быстрее потому, что в этом случае MySQL не производит запись на диск содержимого кэша ключей для заблокированных таблиц, пока не будет вызвана команда UNLOCK TABLES
(обычно кэш ключей записывается на диск после каждой SQL-команды). Применение LOCK TABLES
увеличивает скорость записи/обновления/удаления в таблицах типа MyISAM
.LOCK TABLES
для гарантии, что никакой другой поток не вклинился между операциями SELECT
и UPDATE
. Ниже показан пример, требующий использования LOCK TABLES
для успешного выполнения операций:
mysql> LOCK TABLES trans READ, customer WRITE; mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id; mysql> UPDATE customer SET total_value=sum_from_previous_statement WHERE customer_id=some_id; mysql> UNLOCK TABLES;Без использования
LOCK TABLES
существует вероятность того, что какой-либо иной поток управления может вставить новую строку в таблицу trans
между выполнением операций SELECT
и UPDATE
.
Используя пошаговые обновления (UPDATE customer SET value=value+new_value
) или функцию LAST_INSERT_ID()
, применения команды LOCK TABLES
во многих случаях можно избежать.
Некоторые проблемы можно также решить путем применения блокирующих функций на уровне пользователя GET_LOCK()
и RELEASE_LOCK()
. Эти блоки хранятся в хэш-таблице на сервере и, чтобы обеспечить высокую скорость, реализованы в виде pthread_mutex_lock()
и pthread_mutex_unlock()
. See section 6.3.6.2 Разные функции.
Чтобы получить дополнительную информацию о механизме блокировки, обращайтесь к разделу section 5.3.1 Как MySQL блокирует таблицы.
Можно блокировать все таблицы во всех базах данных блокировкой READ
с помощью команды FLUSH TABLES WITH READ LOCK
. See section 4.5.3 Синтаксис команды FLUSH
. Это очень удобно для получения резервной копии файловой системы, подобной Veritas, при работе в которой могут потребоваться заблаговременные копии памяти.
Примечание: Команда LOCK TABLES
не сохраняет транзакции и автоматически фиксирует все активные транзакции перед попыткой блокировать таблицы.
Posted by Lars Geisler on Friday October 18 2002, @12:51pm | [Delete] [Edit] |
Remember to lock ALL tables you need between LOCK TABLES and UNLOCK TABLES, including tables you just read from! otherwise you will get error 1100: table 'a' not locked in LOCKED TABLES
Add your own comment.