Sorry voor het lange antwoord, maar dit moet in meerdere delen worden beantwoord.
LOCK TABLES
in het algemeen
LOCK TABLES
gebruiken met InnoDB werkt inderdaad en kan worden gedemonstreerd met twee exemplaren van de MySQL CLI die zijn verbonden met dezelfde server (aangeduid met mysql-1
en mysql-2
) in het onderstaande voorbeeld. Het moet over het algemeen worden vermeden in elke productiecontext vanwege de impact op klanten, maar soms kan het de enige optie zijn.
Maak een tabel en vul deze met enkele gegevens:
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
Vergrendel de tafel:
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Probeer in te voegen vanuit mysql-2
, die aan het slot zal wachten:
mysql-2> insert into a (id) values (4);
Ontgrendel nu de tabel van mysql-1
:
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
En tot slot mysql-2
deblokkeert en retourneert:
Query OK, 1 row affected (6.30 sec)
Uw testmethode met phpMyAdmin is ongeldig omdat phpMyAdmin geen permanente verbinding met de server onderhoudt tussen query's vanuit de webinterface. Om elke vorm van vergrendeling te gebruiken LOCK TABLES
, START TRANSACTION
, enz., moet u een verbinding behouden terwijl de vergrendelingen worden vastgehouden.
De manier waarop MySQL tabellen vergrendelt, als je eenmaal LOCK TABLES
hebt gebruikt om iets expliciet te vergrendelen, hebt u geen toegang tot andere tabellen die niet expliciet zijn vergrendeld tijdens de LOCK
... UNLOCK
sessie. In je bovenstaande voorbeeld moet je het volgende gebruiken:
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Ik neem aan table2
gebruikt in de subselectie was geen typfout.)
RENAME TABLE
Bovendien moet ik er rekening mee houden dat het vervangen van de bestaande tabel met behulp van DROP TABLE
gevolgd door RENAME TABLE
zal een kort moment veroorzaken waar de tabel niet bestaat, en dit kan klanten in verwarring brengen die verwachten dat deze wel bestaat. Het is over het algemeen veel beter om:
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Dit zal een atomaire verwisseling van de twee tabellen uitvoeren.