Perdón por la respuesta larga, pero esto deberá responderse en varias partes.
LOCK TABLES
en general
Usando LOCK TABLES
con InnoDB de hecho funciona, y se puede demostrar con dos instancias de MySQL CLI conectadas al mismo servidor (indicado por mysql-1
y mysql-2
) en el siguiente ejemplo. Por lo general, debe evitarse en cualquier tipo de contexto de producción debido al impacto en los clientes, pero a veces puede ser la única opción.
Cree una tabla y complétela con algunos datos:
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
Bloquear la mesa:
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Intenta insertar desde mysql-2
, que colgará esperando en el candado:
mysql-2> insert into a (id) values (4);
Ahora desbloquea la tabla desde mysql-1
:
mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
Y finalmente mysql-2
desbloquea y devuelve:
Query OK, 1 row affected (6.30 sec)
Su método de prueba usando phpMyAdmin no es válido porque phpMyAdmin no mantiene una conexión persistente con el servidor entre consultas desde su interfaz web. Para utilizar cualquier tipo de bloqueo LOCK TABLES
, START TRANSACTION
, etc., debe mantener una conexión mientras se mantienen los bloqueos.
La forma en que MySQL bloquea las tablas, una vez que haya utilizado LOCK TABLES
para bloquear explícitamente algo, no podrá acceder a ninguna otra tabla que no haya sido bloqueada explícitamente durante el LOCK
... UNLOCK
sesión. En su ejemplo anterior, necesita usar:
LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Supongo que table2
usado en la subselección no fue un error tipográfico).
RENAME TABLE
Además, debo señalar que reemplazar la tabla existente usando DROP TABLE
seguido de RENAME TABLE
provocará un breve momento en el que la tabla no existe, y esto puede confundir a los clientes que esperan que exista. Generalmente es mucho mejor hacer:
CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Esto realizará un intercambio atómico de las dos tablas.