Съжалявам за дългия отговор, но ще трябва да се отговори на няколко части.
1. За заключване на InnoDB таблици с LOCK TABLES
като цяло
Използване на LOCK TABLES
с InnoDB всъщност работи и може да се демонстрира с два екземпляра на MySQL CLI, свързани към един и същ сървър (обозначен с mysql-1
и mysql-2
) в примера по-долу. Като цяло трябва да се избягва във всякакъв вид производствен контекст поради въздействието върху клиентите, но понякога може да бъде единствената опция.
Създайте таблица и я попълнете с някои данни:
mysql-1> create table a (id int not null primary key) engine=innodb;
Query OK, 0 rows affected (0.02 sec)
mysql-1> insert into a (id) values (1), (2), (3);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
Заключете масата:
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Опитайте да вмъкнете от mysql-2
, който ще виси в очакване на ключалката:
mysql-2> insert into a (id) values (4);
Сега отключете таблицата от mysql-1
:
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
И накрая mysql-2
деблокира и връща:
Query OK, 1 row affected (6.30 sec)
2. Използване на phpMyAdmin за тестване
Вашият метод за тестване с помощта на phpMyAdmin е невалиден, защото phpMyAdmin не поддържа постоянна връзка със сървъра между заявките от своя уеб интерфейс. За да използвате всякакъв вид заключващи LOCK TABLES
, START TRANSACTION
и т.н., трябва да поддържате връзка, докато ключалките са задържани.
3. Заключване на всички необходими маси по време на работата
Начинът, по който MySQL заключва таблици, след като сте използвали LOCK TABLES
за да заключите изрично нещо, няма да имате достъп до други таблици, които не са били заключени изрично по време на LOCK
... UNLOCK
сесия. В горния пример трябва да използвате:
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Предполагам table2
използван в подизбора не е правописна грешка.)
4. Атомна размяна на таблици с помощта на RENAME TABLE
Освен това трябва да отбележа, че замяната на съществуващата таблица с помощта на DROP TABLE
последвано от RENAME TABLE
ще предизвика кратък момент, в който таблицата не съществува и това може да обърка клиентите, които очакват тя да съществува. По принцип е много по-добре да направите:
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Това ще извърши атомна размяна на двете таблици.