Désolé pour la longue réponse, mais il faudra y répondre en plusieurs parties.
LOCK TABLES
en général
Utilisation de LOCK TABLES
avec InnoDB fonctionne en fait, et peut être démontré avec deux instances de MySQL CLI connectées au même serveur (noté par mysql-1
et mysql-2
) dans l'exemple ci-dessous. Cela devrait généralement être évité dans tout type de contexte de production en raison de l'impact sur les clients, mais parfois cela peut être la seule option.
Créez un tableau et remplissez-le avec des données :
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
Verrouiller la table :
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Essayez d'insérer depuis mysql-2
, qui se bloquera en attente sur la serrure :
mysql-2> insert into a (id) values (4);
Déverrouillez maintenant la table depuis mysql-1
:
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
Et enfin mysql-2
débloque et renvoie :
Query OK, 1 row affected (6.30 sec)
Votre méthode de test utilisant phpMyAdmin n'est pas valide car phpMyAdmin ne maintient pas une connexion persistante au serveur entre les requêtes de son interface Web. Afin d'utiliser n'importe quel type de verrouillage LOCK TABLES
, START TRANSACTION
, etc., vous devez maintenir une connexion pendant que les verrous sont maintenus.
La façon dont MySQL verrouille les tables, une fois que vous avez utilisé LOCK TABLES
pour verrouiller explicitement quoi que ce soit, vous ne pourrez accéder à aucune autre table qui n'a pas été verrouillée explicitement pendant le LOCK
... UNLOCK
session. Dans votre exemple ci-dessus, vous devez utiliser :
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Je suppose table2
utilisé dans la sous-sélection n'était pas une faute de frappe.)
RENAME TABLE
De plus, je dois noter que le remplacement de la table existante à l'aide de DROP TABLE
suivi de RENAME TABLE
provoquera un bref moment où la table n'existe pas, et cela peut dérouter les clients qui s'attendent à ce qu'elle existe. Il est généralement préférable de faire :
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Cela effectuera un échange atomique des deux tables.