Sintaxe LOCK TABLES e UNLOCK TABLES


LOCK TABLES bloqueia tabelas para a thread atual. UNLOCK TABLES libera qualquer trava existente para a thread atual. Todas as tabela que estão bloqueadas pela thread atual são implicitamente desbloquadas quando a thread executa um outro LOCK TABLES, ou quando a conexão ao servidor é fechada.

Para usar LOCK TABLES no MariaDB 4.0.2 você precisa do privilégio global LOCK TABLES e um privilégio SELECT nas tabelas envolvidas No MariaDB 3.23 você precisa ter os privilégios SELECT, insert, DELETE e UPDATE para as tabelas.

A razão principal para utilizar LOCK TABLES é para emular transações ou obter mais velocidade ao atualizar tabelas. Isto é explicado em mais detalhes posteriormente.

Se uma thread obtem uma trava de leitura (READ) em uma tabela, aquela thread (e todas as outras threads) só poderão ler da tabela. Se uma thread obter uma trava de escrita (WRITE) na tabela, apenas a thread que bloqueou poderá ler ou escrever na tabela. Outras threads serão bloqueadas.

A diferença entre READ LOCAL e READ é que READ LOCAL permite que instruções INSERT não conflitantes sejam executadas enquanto a trava está ativa. Isto, no entatnto, não pode ser usado se você for manipular o arquivo de banco de dados fora do MariaDB enquanto a trava estiver ativa.

Quando você usa LOCK TABLES, você deve travar todas as tabelas que você for usar e utilizar o mesmo alias que estiver utilizando em suas consultas! Se você estiver usando uma tabela várias vezes em uma consulta (com aliases), você deve obter um trava para cada alias.

Bloqueio de escrita (WRITE) normalmente têm maior prioridade que bloqueio de leitura (READ), para assegurar que atualizações são processadas assim que possível. Isto significa que se uma thread obtida um bloqueio de leitura (READ) e outra thread requisitar um bloqueio de escrita (WRITE), bloqueios de leitura (READ) subsequentes irão esperar até a thread de escrita (WRITE) tiver obtido a trava e a liberado. Você pode usar travas LOW_PRIORITY WRITE para permitir que outras threads obtenham bloqueios de leitura (READ) enquanto a thread estiver esperando pela trava de escrita (WRITE). Você só deve utilizar bloqueios LOW_PRIORITY WRITE se você estiver certo que haverá um momento onde nenhuma thread terá bloqueio de leitura (READ).

LOCK TABLES funciona da seguinte maneira:

  1. Ordene todas as tabelas a serem travadas em uma ordem definida internamente (do ponto do usuário a ordem é indefinida).
  2. Se uma tabela é bloqueada com uma trava de leitura e de escrita, coloque a trava de escrita antes da trava de leitura.
  3. Bloqueie uma tabela por vez até que a thread obtenha todas as travas.

Esta política assegura que as tabelas sejam bloqueadas sem deadlock. Há no entanto outra coisa da qual é preciso estar ciente neste esquema:

Se cocê estiver usando uma trava de escita LOW_PRIORITY WRITE em uma tabela, significa apenas que o MariaDB irá esperar por esta trava particular até que não haja mais treads fazendo um bloqueio de leitura (READ). Quando a thread tiver obtido a trava de escrita (WRITE) e está esperando ppo obter o trava para a próxima tabela na lista de tabelas bloqueadas, todas as outras threads irão esperar que a trva de escrita (WRITE) seja liberada. Se isto tornar um sério problema com sua aplicação, você deve converter algumas de suas tabellas para tabelas com segurança em transações.

Você pode matar com segurança um thread que está esperando por um bloqueio de tabela com KILL. Leia "Sintaxe de KILL".

Note que você não deve travar nenhuma tabela que você esteja usando com INSERT DELAYED. Isto é porque este é o caso que o INSERT é feito por uma thread separada.

Normalmente, você não tem que travar tabelas, já que todas as instruções UPDATE são atomicas; nenhuma outra thread pode interferir com qualquer outra executando uma instrução SQL. Existem poucos casos em que você gostaria de travar as tabelas de qualquer forma:

Utilizando atualizações incrementais (UPDATE customer SET value=value+new_value) ou a função LAST_INSERT_ID()i, você pode evitar o uso de LOCK TABLES em muitos casos.

Você também pode resolver alguns casos usando as funções de bloqueio a nível de usuário GET_LOCK() e RELEASE_LOCK(). Estas travas são salvas em uma tabela hash no servidor e implementado com pthread_mutex_lock() e pthread_mutex_unlock() para alta velocidade. Leia "Funções Diversas".

Veja "Como o MariaDB Trava as Tabelas", para mais informações sobre política de bloqueios.

Você pode trocar todas as tabelas em todos os banco de dados com trava de leitura com o comando FLUSH TABLES WITH READ LOCK. Leia "Sintaxe de FLUSH". Este é um modo muito conveiente de tirar backups se você tiver um sistema de arquivos, como Veritas, que pode tirar snapshots.

NOTE: LOCK TABLES mão é seguro com transações e fará um commit implicitamente em qualquer transação ativa antes de tentar travar as tabelas.

Retornar