LOCK

Name

LOCK  --  bloqueia explicitamente uma tabela

Synopsis

LOCK [ TABLE ] nome [, ...]
LOCK [ TABLE ] nome [, ...] IN modo_de_bloqueio MODE

onde modo_de_bloqueio é um entre:

	ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE |
	SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
  

Entradas

nome

O nome de uma tabela existente a ser bloqueada.

ACCESS SHARE MODE

Note: Este modo de bloqueio é obtido automaticamente nas tabelas sendo consultadas.

Este é o modo de bloqueio menos restritivo. Somente conflita com o modo ACCESS EXCLUSIVE. É utilizado para proteger a tabela de ser modificada por um comando ALTER TABLE, DROP TABLE ou VACUUM FULL concorrente.

ROW SHARE MODE

Note: Automaticamente obtido pelo comando SELECT ... FOR UPDATE.

Conflita com os modos de bloqueio EXCLUSIVE e ACCESS EXCLUSIVE.

ROW EXCLUSIVE MODE

Note: Automaticamente obtido pelos comandos UPDATE, DELETE, e INSERT.

Conflita com os modos de bloqueio SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE.

SHARE UPDATE EXCLUSIVE MODE

Note: Automaticamente obtido pelo comando VACUUM (sem a opção FULL).

Conflita com os modos de bloqueio SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE. Este modo de bloqueio protege a tabela contra alterações concorrentes do esquema e VACUUM.

SHARE MODE

Note: Automaticamente obtido pelo comando CREATE INDEX. Bloqueia o compartilhamento de toda a tabela.

Conflita com os modos de bloqueio ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE. Este modo de bloqueio protege a tabela contra atualização concorrente dos dados.

SHARE ROW EXCLUSIVE MODE

Note: Semelhante ao EXCLUSIVE MODE, mas permite o bloqueio ROW SHARE por outros.

Conflita com os modos de bloqueio ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE.

EXCLUSIVE MODE

Note: Este modo é ainda mais restritivo do que SHARE ROW EXCLUSIVE. Bloqueia todas as consultas ROW SHARE/SELECT...FOR UPDATE concorrentes.

Conflita com os modos de bloqueio ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE e ACCESS EXCLUSIVE. Este modo de bloqueio permite somente o ACCESS SHARE concorrente, ou seja, somente leituras na tabela podem ocorrer em paralelo a uma transação contendo este tipo de bloqueio.

ACCESS EXCLUSIVE MODE

Note: Automaticamente obtido pelos comandos ALTER TABLE, DROP TABLE e VACUUM FULL. Este é o modo de bloqueio mais restritivo, o qual protege uma tabela bloqueada de qualquer operação concorrente.

Note: Este modo de bloqueio também é obtido por um comando LOCK TABLE não qualificado (ou seja, o comando sem a opção do modo de bloqueio explicitado).

Conflita com todos os outros modos de bloqueio.

Saídas

LOCK TABLE

Mensagem retornada se o bloqueio for obtido com sucesso.

ERROR nome: Table does not exist.

Mensagem retornada se nome não existir.

Descrição

O comando LOCK TABLE controla o acesso concorrente à tabela durante o tempo de execução da transação. O PostgreSQL sempre utiliza o modo de bloqueio menos restritivo quando é possível. O comando LOCK TABLE é usado nos casos onde se necessita de um modo de bloqueio mais restritivo.

Os bloqueios dos SGBDR utilizam a seguinte terminologia:

EXCLUSIVE

Um bloqueio exclusivo impede a concessão de outros bloqueios do mesmo tipo (Nota: O modo ROW EXCLUSIVE não segue esta convenção de nome perfeitamente, porque é compartilhado no nível de tabela; é exclusivo apenas com relação às linhas específicas que estão sendo atualizadas).

SHARE

Um bloqueio compartilhado permite que outros também obtenham o mesmo tipo de bloqueio, mas impede que o bloqueio EXCLUSIVE correspondente seja concedido.

ACCESS

Bloqueia o esquema da tabela.

ROW

Bloqueia linhas individualmente.

Por exemplo, suponha que um aplicativo processe uma transação no nível de isolamento READ COMMITTED e precise garantir a persistência dos dados da tabela durante a transação. Para conseguir esta persistência, pode-se obter o modo de bloqueio SHARE na tabela antes de realizar a consulta. Este procedimento impede alterações de dados concorrentes e garante que as operações de leitura posteriores na tabela acessam os dados no estado atual, porque o modo de bloqueio SHARE conflita com qualquer modo de bloqueio ROW EXCLUSIVE necessário para escrever. O comando LOCK TABLE nome IN SHARE MODE aguarda até que todas as operações de escrita concorrentes terminem efetivando ou desfazendo suas transações. Portanto, quando este bloqueio é conseguido, não existe nenhuma operação de escrita sendo executada.

Note: Para ler os dados em seu estado corrente atual ao executar uma transação no nível de isolamento SERIALIZABLE, é necessário executar o comando LOCK TABLE antes de executar qualquer comando da DML. A visão dos dados de uma transação serializável é congelada no momento em que o primeiro comando da DML começa a executar.

Além dos requisitos acima, se uma transação altera os dados da tabela, então o modo de bloqueio SHARE ROW EXCLUSIVE deve ser obtido para prevenir a ocorrência da condição de "impasse" (deadlock), quando duas transações concorrentes bloqueiam a tabela em modo SHARE e depois tentam mudar os dados desta tabela, as duas (implicitamente) solicitando o modo de bloqueio ROW EXCLUSIVE que conflita com o modo de bloqueio SHARE concorrente.

Para que não ocorra a situação de "impasse" (quando duas transações ficam aguardando uma pela outra) descrita acima, devem ser seguidas duas regras gerais que evitam as condições de impasse:

Note: O PostgreSQL detecta "impasses" (deadlocks) e desfaz pelo menos uma das transações em espera para resolver o impasse.

Ao se bloquear várias tabelas, o comando LOCK a, b; é equivalente a LOCK a; LOCK b;. As tabelas são bloqueadas uma por uma na ordem especificada pelo comando LOCK.

Notas

O comando LOCK ... IN ACCESS SHARE MODE requer o privilégio SELECT na tabela especificada. Todas as outras formas de LOCK requerem os privilégios UPDATE e/ou DELETE.

O comando LOCK é útil apenas dentro de um bloco de transação (BEGIN...COMMIT), porque o bloqueio é liberado logo que a transação termina. Um comando LOCK aparecendo fora de um bloco de transação forma uma transação auto-contida, portanto o bloqueio será liberado tão logo seja obtido.

Utilização

Este exemplo mostra o bloqueio no modo SHARE da tabela que contém a chave primária, antes de fazer uma inserção na tabela que contém a chave estrangeira:

BEGIN WORK;
LOCK TABLE filmes IN SHARE MODE;
SELECT id FROM filmes 
    WHERE nome = 'Star Wars: Episode I - The Phantom Menace';
-- Fazer o ROLLBACK se a linha não for encontrada
INSERT INTO filmes_comentarios VALUES 
    (_id_, 'Maravilhoso! Eu estava aguardando por isto há muito tempo!');
COMMIT WORK;
   

Obter o bloqueio no modo SHARE ROW EXCLUSIVE da tabela que contém a chave primária antes de realizar a operação de exclusão:

BEGIN WORK;
LOCK TABLE filmes IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM filmes_comentarios WHERE id IN
    (SELECT id FROM filmes WHERE avaliacao < 5);
DELETE FROM filmes WHERE avaliacao < 5;
COMMIT WORK;
   

Compatibilidade

SQL92

Não existe o comando LOCK TABLE no SQL92, que em seu lugar usa o comando SET TRANSACTION para especificar os níveis de concorrência das transações. O PostgreSQL também suporta esta funcionalidade; Consulte o comando SET TRANSACTION para obter mais detalhes.

Exceto pelos modos de bloqueio ACCESS SHARE, ACCESS EXCLUSIVE e SHARE UPDATE EXCLUSIVE, os modos de bloqueio do PostgreSQL e a sintaxe do comando LOCK TABLE são compatíveis com as presentes no Oracle(TM).