Команда 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 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. Синтаксис команди KILL.
Врахуйте, що не можна блокувати будь-які таблиці, використовувані спільно з оператором INSERT DELAYED. оскільки в цьому випадку команда INSERT виконується як окремий потік.
Зазвичай немає необхідності блокувати таблиці, оскільки всі поодинокі команди UPDATE є неподільними; ніякий інший потік не може взаємодіяти з будь-якої SQL-командою, що виконується в даний час. Однак в деяких випадках переважно тим чи іншим чином здійснювати блокування таблиць:
Якщо передбачається виконати велику кількість операцій на групі взаємозалежних таблиць, то швидше за все це зробити, блокувавши таблиці, які ви збираєтеся використовувати. Звичайно, це має свою зворотну сторону, оскільки ніякий інший потік управління не може оновити таблицю з блокуванням READ або прочитати таблицю з блокуванням WRITE. При блокуванні LOCK TABLES операції виконуються швидше тому, що в цьому випадку MySQL не виробляє запис на диск вмісту кеша ключів для заблокованих таблиць, поки не буде викликана команда UNLOCK TABLES (зазвичай кеш ключів записується на диск після кожної SQL-команди). Застосування LOCK TABLES збільшує швидкість запису / оновлення / видалення в таблицях типу MyISAM.
Якщо ви використовуєте таблиці, які не підтримують транзакцій, то при використанні програми обробки таблиць необхідно застосовувати команду LOCK TABLES для гарантії, що ніякий інший потік не вклинився між операціями SELECT і UPDATE. Нижче показаний приклад, що вимагає використання LOCK 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 (). Різні функції.
Щоб отримати додаткову інформацію про механізм блокування, звертайтеся до розділу Як MySQL блокує таблиці.
Можна блокувати всі таблиці у всіх базах даних блокуванням READ за допомогою команди FLUSH TABLES WITH READ LOCK. Синтаксис команди FLUSH. Це дуже зручно для отримання резервної копії файлової системи, подібної Veritas, при роботі в якій можуть знадобитися завчасні копії пам'яті.
Примітка: Команда LOCK TABLES не зберігається транзакції і автоматично фіксує всі активні транзакції перед спробою блокувати таблиці.