Оператори управління транзакціями і блокуванням mysql - html, css, javascript, perl, php, mysql
Синтаксис START TRANSACTION, COMMITі ROLLBACK
Оператори, коториенельзяоткатіть
Для деяких операторів не можна виконати відкат за допомогою ROLLBACK. В їх число входять оператори мови визначення даних (Data Definition Language - DDL), які створюють і знищують бази даних, а також створюють, видаляють і змінюють таблиці.
Ви повинні проектувати свої транзакції таким чином, щоб вони не включали в себе ці оператори. Якщо ввести такий оператор на початку транзакції, яка не може бути відкатали, і потім наступний оператор пізніше завершиться аварійно, повний ефект транзакції не може бути скасований оператором ROLLBACK.
Оператори, визивающіенеявнийCOMMIT
Наступні оператори неявно завершують транзакцію (як якщо б перед їх виконанням був виданий COMMIT):
UNLOCK TABLES також завершує транзакцію, якщо будь-які таблиці були блоковані. До MySQL 4.0.13 CREATE TABLE завершував транзакцію, якщо була б включена бінарна реєстрація.
Транзакції не можуть бути вкладеними. Це наслідок того, що неявний COMMIT виконується для будь-якої поточної транзакції, коли виконується оператор start TRANSACTION або його синоніми.
6.4.4.Сінтаксіс SAVEPOINTі ROLLBACK TO SAVEPOINT
SAVEPOINT ідентифікатор
ROLLBACK TO SAVEPOINT ідентифікатор
Починаючи з версій MySQL 4.0.14 і 4.1.1, innoDB підтримує SQL-оператори SAVEPOINT і ROLLBACK TO SAVEPOINT.
Оператор SAVEPOINT встановлює іменовану точку початку транзакції з ім'ям ідентифікатор. Якщо поточна транзакція вже має точку збереження з таким же ім'ям, стара точка віддаляється і встановлюється нова.
Оператор ROLLBACK TO SAVEPOINT відкочується транзакцію до іменованої точці збереження. Модифікації рядків, які виконувалися поточної транзакцією після цієї точки, скасовуються відкотом, однак InnoDB не знімає блокування рядків, які були встановлені в пам'яті після точки збереження. (Відзначимо, що для знову вставлених рядків інформація про блокування спирається на ідентифікатор транзакції, збережений в рядку, блокування не зберігається в пам'яті окремо. У цьому випадку блокування рядки знімається при скасуванні.) Точки збереження, встановлені в більш пізні моменти, ніж іменована точка, видаляються.
Якщо оператор повертає наступну помилку, це означає, що названа точка збереження не існує:
ERROR 1181: Got error 153 during ROLLBACK
Всі точки збереження транзакцій віддаляються, якщо виконується оператор COMMIT або ROLLBACK без вказівки імені точки збереження.
Синтаксис LOCK TABLESі UNLOCK TABLES
І навпаки, якщо таблиця блокована за псевдонімом, ви повинні звертатися до неї, використовуючи цей псевдонім:
mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * ШЖ t;
ERROR 1100 Table Ч1 was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;
Блокування по запису (WRITE) зазвичай мають більш високий пріоритет, ніж блокування з читання (READ), щоб гарантувати, що оновлення даних пройдуть якомога швидше. Це означає, що якщо один потік отримує блокування з читання, а потім інший потік запитує блокування по запису, то наступні запити на блокування з читання чекатимуть, поки не буде встановлена і знято блокування по запису. Ви можете використовувати блокування по запису зі зниженим пріоритетом (LOW_PRIORITY WRITE), щоб дозволити іншим потокам встановлювати блокування з читання, поки поточний потік очікує можливості поставити блокування по запису. Ви повинні встановлювати блокування LOW_PRIORITY WRITE тільки тоді, коли впевнені, що в процесі роботи сервера буде час, коли жоден з потоків не буде утримувати блокування з читання.
LOCK TABLES працює наступним чином:
- У певному внутрішньому порядку сортуються всі таблиці, що підлягають блокуванню. З точки зору користувача, цей порядок не визначено.
- Якщо таблиця блокується і з читання та по запису, встановлюється блокування запису перед блокуванням читання.
- Блокується по одній таблиці за раз до тих пір, поки потік не отримає всі блокування.
Якщо ви використовуєте блокування LOW_PRIORITY WRITE для таблиці, це означає тільки, що MySQL чекатиме моменту, коли не буде жодного потоку, який бажає встановити блокування читання. Коли потоку вдається встановити блокування записи однієї таблиці, і він очікує можливості заблокувати таку таблицю в списку, всі інші потоки будуть припинені до тих пір, поки блокування записі не буде знята. Якщо це становить серйозну проблему для ваших додатків, ви повинні розглянути можливість перетворення деяких ваших таблиць в нетран-закціонную форму.
Можна безпечно використовувати KILL для переривання потоку, який очікує блокування таблиці. Див. Розділ 6.5.4.3.
Зауважте, що ви не повинні блокувати ніяких таблиць з тих, в яких виконуєте INSERT DELAYED, тому що в цьому випадку INSERT виконується окремим потоком сервера.
Зазвичай вам не потрібно блокувати таблиці, оскільки всі окремі оператори INSERT атомарний - тобто ніякий інший потік не може втрутитися в виконуваний в даний момент SQL-оператор. Однак існують випадки, коли блокувати таблиці все ж необхідно:
- Якщо ви збираєтеся виконувати безліч операцій над набором таблиць MyISAM, то набагато швидше вийде, якщо їх попередньо заблокувати. Блокування таблиць MyISAM прискорює вставку, оновлення або видалення в них. Негативна сторона цього полягає в тому, що жоден потік не може оновлювати заблоковану з читання таблицю (включаючи той, що встановив блокування), і жоден потік не може отримати ніякого доступу до таблиці, заблокованої за записом, крім потоку, який встановив блокування.
Причина того, що деякі операції MylSAM працюють швидше на блокованих таблицях, пов'язана з тим, що MySQL не скидати на диск індексний кеш для цих таблиць до тих пір, поки не буде викликаний UNLOCK TABLES. Зазвичай індексні кеші скидаються після кожного SQL-оператора. - Якщо ви використовуєте механізм зберігання MySQL, які не підтримує транзакцій, ви повинні видавати LOCK TABLES, якщо хочете гарантувати, що між SELECT і UPDATE НЕ будуть видані інші оператори. Наведений нижче приклад вимагає LOCK TABLES для безпечного виконання:
mysql> LOCKTABLEStransREAD, customerWRITE;
mysql> SELECT SUM (value) FROM trans WHEREcustomer_2.6. = ідентифікатор;
mysql> UPDATE customer
-> SETЬоЬа1_уа1'е = сумма_із_предццущ<2го_оператора
-> WHEREсізЬотег_1<к=идентификатор; mysql> UNLOCK TABLES;
Без LOCK TABLES існує можливість того, що інший потік може вставити новий рядок в таблицю trans між виконанням ваших операторів SELECT і UPDATE.
Ви можете уникнути застосування LOCK TABLES в багатьох випадках, застосовуючи відносні поновлення (UPDATE customer SET value = value + new_value), або функцію LAST_INSERT_ID (). Див. Розділ Транзакції і атомарні операції
Уникнути блокування таблиць можна також в деяких випадках, використовуючи функції користувальницького рівня GET_LOCK () і RELEASE_LOCK (). Ці блокування зберігаються в хеш-таблиці на сервері і для швидкості реалізуються викликами pthread_mutex_lock () і pthread_mutex_unlock (). Див. Розділ Різні функції
Ви можете заблокувати з читання все таблиці у всіх базах даних оператором flush tables with read LOCK. Див. РазделСінтаксіс LOCK TABLES і UNLOCK TABLES Це дуже зручний спосіб отримати резервні копії, якщо ви працюєте з файлової системою на кшталт Veritas, яка може робити знімки в часі.
%На замітку! Якщо ви використовуєте ALTER TABLE на блокованої таблиці, вона може розблокуватися. Див. Розділ Проблеми з ALTER TABLE
Синтаксис SET TRANSACTION
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVELВи можете також встановити початковий глобальний рівень ізоляції для сервера mysqld, запустивши його з опцією -transaction-isolation