Resumo : neste tutorial, você aprenderá como usar o bloqueio do MySQL para acessos cooperativos a tabelas entre sessões.
Um bloqueio é um sinalizador associado a uma tabela. O MySQL permite que uma sessão cliente adquira explicitamente um bloqueio de tabela para evitar que outras sessões acessem a mesma tabela durante um período específico.
Uma sessão de cliente pode adquirir ou liberar bloqueios de tabela somente para si mesma. Uma sessão de cliente não pode adquirir ou liberar bloqueios de tabela para outras sessões de cliente.
Antes de prosseguirmos, vamos criar uma tabela chamada messages
para praticar com as instruções de bloqueio de tabela.
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
message VARCHAR(100) NOT NULL
);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Instrução MySQL LOCK TABLES
A LOCK TABLES
instrução a seguir adquire explicitamente um bloqueio de tabela:
LOCK TABLES table_name [READ | WRITE]
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Nesta sintaxe, você especifica o nome da tabela que deseja bloquear após as LOCK TABLES
palavras-chave. Além disso, você especifica o tipo de bloqueio, READ
ou WRITE
.
O MySQL permite bloquear múltiplas tabelas especificando uma lista de nomes de tabelas separados por vírgula com tipos de bloqueio que você deseja bloquear após as LOCK TABLES
palavras-chave:
LOCK TABLES table_name1 [READ | WRITE],
table_name2 [READ | WRITE],
... ;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Instrução MySQL UNLOCK TABLES
A instrução UNLOCK TABLES libera quaisquer bloqueios de tabela mantidos pela sessão atual:
UNLOCK TABLES;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
READ
Fechaduras
Uma READ
fechadura possui os seguintes recursos:
- Um
READ
bloqueio para uma tabela pode ser adquirido por múltiplas sessões ao mesmo tempo. Além disso, outras sessões podem ler dados da tabela sem adquirir o bloqueio. - A sessão que mantém o
READ
bloqueio só pode ler dados da tabela, mas não pode gravar. E outras sessões não podem gravar dados na tabela até que oREAD
bloqueio seja liberado. As operações de gravação de outra sessão serão colocadas em estado de espera até que oREAD
bloqueio seja liberado. - Se a sessão for encerrada, normalmente ou anormalmente, o MySQL irá liberar todos os bloqueios implicitamente. Este recurso também é relevante para o
WRITE
bloqueio.
Vamos dar uma olhada em como o READ
bloqueio funciona no cenário a seguir.
Primeiro, conecte-se ao banco de dados na primeira sessão e use a CONNECTION_ID()
função para obter o ID de conexão atual da seguinte forma:
SELECT CONNECTION_ID();
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Em seguida, insira uma nova linha na messages
tabela.
INSERT INTO messages(message)
VALUES('Hello');
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Em seguida, consulte os dados da messages
tabela.
SELECT * FROM messages;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Depois disso, adquira um bloqueio usando o LOCK TABLE
extrato.
LOCK TABLE messages READ;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Finalmente, tente inserir uma nova linha na messages
tabela:
INSERT INTO messages(message)
VALUES('Hi');
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
MySQL emitiu o seguinte erro:
Error Code: 1099. Table 'messages' was locked with a READ lock and can't be updated.
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Assim, uma vez READ
adquirido o bloqueio, você não poderá gravar dados na tabela na mesma sessão.
Vamos verificar o READ
bloqueio de uma sessão diferente.
Primeiro, conecte-se ao banco de dados e verifique o ID da conexão:
SELECT CONNECTION_ID();
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Em seguida, consulte os dados da messages
tabela:
SELECT * FROM messages;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Em seguida, insira uma nova linha na messages
tabela:
INSERT INTO messages(message)
VALUES('Bye');
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Aqui está a saída:
A operação de inserção da segunda sessão está em estado de espera porque um bloqueio READ já foi adquirido na tabela de mensagens pela primeira sessão e ainda não foi liberado.
Desde a primeira sessão, use a SHOW PROCESSLIST
declaração para mostrar informações detalhadas:
SHOW PROCESSLIST;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Depois disso, volte para a primeira sessão e libere o bloqueio usando a UNLOCK TABLES
instrução. Depois de liberar o READ
bloqueio da primeira sessão, a INSERT
operação da segunda sessão será executada.
Por fim, verifique os dados da messages
tabela para ver se a INSERT
operação da segunda sessão foi executada.
SELECT * FROM messages;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Gravar bloqueios
Uma WRITE
fechadura possui os seguintes recursos:
- A única sessão que mantém o bloqueio de uma tabela pode ler e gravar dados da tabela.
- Outras sessões não podem ler e gravar dados na tabela até que o
WRITE
bloqueio seja liberado.
Vamos entrar em detalhes para ver como WRITE
funciona o bloqueio.
Primeiro, adquira um WRITE
bloqueio desde a primeira sessão.
LOCK TABLE messages WRITE;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Em seguida, insira uma nova linha na messages
tabela.
INSERT INTO messages(message)
VALUES('Good Morning');
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Funcionou.
Em seguida, consulte os dados da messages
tabela.
SELECT * FROM messages;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Também funciona.
Depois disso, a partir da segunda sessão, tente escrever e ler os dados:
INSERT INTO messages(message)
VALUES('Bye Bye');
SELECT * FROM messages;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
O MySQL coloca essas operações em estado de espera. Você pode verificar isso usando a SHOW PROCESSLIST
declaração:
SHOW PROCESSLIST;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Por fim, libere o bloqueio da primeira sessão.
UNLOCK TABLES;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Você verá todas as operações pendentes da segunda sessão executada e a imagem a seguir ilustra o resultado:
Bloqueios de leitura versus gravação
- Os bloqueios de leitura são bloqueios “compartilhados” que evitam que um bloqueio de gravação seja adquirido, mas não outros bloqueios de leitura.
- Os bloqueios de gravação são bloqueios “exclusivos” que impedem qualquer outro bloqueio de qualquer tipo.
Neste tutorial, você aprendeu como bloquear e desbloquear tabelas para cooperar com os acessos às tabelas entre sessões.