Ci scusiamo per la lunga risposta, ma sarà necessario rispondere in più parti.
LOCK TABLES
in generale
Usando LOCK TABLES
con InnoDB funziona infatti e può essere dimostrato con due istanze della CLI MySQL collegate allo stesso server (indicato da mysql-1
e mysql-2
) nell'esempio seguente. In genere dovrebbe essere evitato in qualsiasi tipo di contesto di produzione a causa dell'impatto sui clienti, ma a volte può essere l'unica opzione.
Crea una tabella e popolala con alcuni dati:
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
Blocca il tavolo:
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Prova a inserire da mysql-2
, che si bloccherà in attesa sul lucchetto:
mysql-2> insert into a (id) values (4);
Ora sblocca la tabella da mysql-1
:
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
E infine mysql-2
sblocca e restituisce:
Query OK, 1 row affected (6.30 sec)
Il tuo metodo di test che utilizza phpMyAdmin non è valido perché phpMyAdmin non mantiene una connessione persistente al server tra le query dalla sua interfaccia web. Per utilizzare qualsiasi tipo di blocco LOCK TABLES
, START TRANSACTION
, ecc., è necessario mantenere una connessione mentre i blocchi sono mantenuti.
Il modo in cui MySQL blocca le tabelle, una volta che hai usato LOCK TABLES
per bloccare qualcosa in modo esplicito, non sarai in grado di accedere ad altre tabelle che non sono state bloccate esplicitamente durante il LOCK
... UNLOCK
sessione. Nel tuo esempio sopra, devi usare:
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Sto assumendo table2
utilizzato nella sottoselezione non era un errore di battitura.)
RENAME TABLE
Inoltre, dovrei notare che la sostituzione della tabella esistente utilizzando DROP TABLE
seguito da RENAME TABLE
causerà un breve momento in cui la tabella non esiste e ciò potrebbe confondere i client che si aspettano che esista. In genere è molto meglio fare:
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Questo eseguirà uno scambio atomico delle due tabelle.