Desculpe a resposta longa, mas isso precisará ser respondido em várias partes.
1. Ao bloquear tabelas InnoDB com
LOCK TABLES
em geral Usando
LOCK TABLES
com InnoDB funciona de fato, e pode ser demonstrado com duas instâncias da CLI do MySQL conectadas ao mesmo servidor (indicado por mysql-1
e mysql-2
) no exemplo abaixo. Geralmente deve ser evitado em qualquer tipo de contexto de produção devido ao impacto para os clientes, mas às vezes pode ser a única opção. Crie uma tabela e preencha-a com alguns dados:
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
Bloqueie a mesa:
mysql-1> lock tables a write;
Query OK, 0 rows affected (0.00 sec)
Tente inserir de
mysql-2
, que ficará travado aguardando o bloqueio:mysql-2> insert into a (id) values (4);
Agora desbloqueie a tabela de
mysql-1
:mysql-1> unlock tables;
Query OK, 0 rows affected (0.00 sec)
E finalmente
mysql-2
desbloqueia e retorna:Query OK, 1 row affected (6.30 sec)
2. Usando phpMyAdmin para teste
Seu método de teste usando o phpMyAdmin é inválido porque o phpMyAdmin não mantém uma conexão persistente com o servidor entre as consultas de sua interface web. Para usar qualquer tipo de bloqueio
LOCK TABLES
, START TRANSACTION
, etc., você precisa manter uma conexão enquanto os bloqueios são mantidos. 3. Bloqueando todas as tabelas necessárias durante o trabalho
A maneira como o MySQL bloqueia as tabelas, uma vez que você tenha usado
LOCK TABLES
para bloquear explicitamente qualquer coisa, você não poderá acessar nenhuma outra tabela que não tenha sido bloqueada explicitamente durante o LOCK
... UNLOCK
sessão. No seu exemplo acima, você precisa usar:LOCK TABLES my_table WRITE, new_table WRITE, table2 READ;
(Estou assumindo
table2
usado na subseleção não foi um erro de digitação.) 4. Troca de tabela atômica usando
RENAME TABLE
Além disso, devo observar que substituir a tabela existente usando
DROP TABLE
seguido por RENAME TABLE
causará um breve momento em que a tabela não existirá, e isso poderá confundir os clientes que esperam que ela exista. Geralmente é muito melhor fazer:CREATE TABLE t_new (...);
<Populate t_new using some method>
RENAME TABLE t TO t_old, t_new TO t;
DROP TABLE t_old;
Isso executará uma troca atômica das duas tabelas.