LOCK

Nome

LOCK -- bloqueia uma tabela

Sinopse

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

Descrição

O comando LOCK TABLE obtém um bloqueio no nível de tabela aguardando, quando necessário, pela liberação de qualquer bloqueio conflitante. Uma vez obtido, o bloqueio é mantido pelo restante da transação corrente (Não existe o comando UNLOCK TABLE; os bloqueios são sempre liberados no final da transação).

Ao obter automaticamente o bloqueio para os comandos que fazem referência a tabelas, o PostgreSQL sempre utiliza o modo de bloqueio menos restritivo possível. O comando LOCK TABLE serve para os casos onde é necessário um modo de bloqueio mais restritivo.

Por exemplo, suponha que uma aplicação executa uma transação no nível de isolamento READ COMMITTED, e precisa garantir que os dados da tabela permaneçam estáveis durante a transação. Para conseguir esta situação pode ser obtido o modo de bloqueio SHARE na tabela antes de realizar a consulta. Isto impede a alteração concorrente dos dados, garantindo que as próximas operações de leitura na tabela vão enxergar uma visão estável de dados efetivados, porque o modo de bloqueio SHARE conflita com o modo de bloqueio ROW EXCLUSIVE obtido por quem está escrevendo, fazendo com que o comando LOCK TABLE nome IN SHARE MODE aguarde todas as transações que obtiveram bloqueio no modo ROW EXCLUSIVE efetivarem ou desfazerem suas modificações. Portanto, quando este bloqueio é obtido não existem escritas não efetivadas pendentes; além disso, nenhuma transação pode começar enquanto o bloqueio não for liberado.

Para obter um efeito semelhante ao executar uma transação no nível de isolamento serializável, é necessário executar o comando LOCK TABLE antes de executar qualquer comando SELECT ou de modificação de dado. A visão dos dados de uma transação serializável é congelada no momento em que seu primeiro comando SELECT ou de modificação de dados começa. Um comando LOCK TABLE posterior na transação ainda vai impedir escritas concorrentes — mas não vai garantir que o que é lido pela transação corresponde aos últimos valores efetivados.

Se uma transação deste tipo altera os dados da tabela, então deve ser utilizado o modo de bloqueio SHARE ROW EXCLUSIVE em vez do modo SHARE, para garantir que somente uma transação deste tipo executa de cada vez. Sem isto, é possível ocorrer um impasse (deadlock): duas transações podem obter o modo de bloqueio SHARE, e depois ficarem impossibilitadas de obter o bloqueio no modo ROW EXCLUSIVE para realizar suas modificações (Deve ser observado que os bloqueios da própria transação nunca entram em conflito e, portanto, a transação pode obter o modo ROW EXCLUSIVE enquanto mantém o modo de bloqueio SHARE — mas não se outra transação estiver com o modo de bloqueio SHARE).

Para evitar os impasses, deve ser garantido que as transações obtêm o bloqueio dos mesmos objetos na mesma ordem e, se vários modos de bloqueio estão envolvidos para um único objeto, as transações devem sempre obter o modo mais restritivo primeiro.

Mais informações sobre os modos de bloqueio e estratégias de bloqueio podem ser encontradas na Seção 12.3 .

Parâmetros

nome
O nome (opcionalmente qualificado pelo esquema) da tabela existente a ser bloqueada. O comando LOCK TABLE a, b; é equivalente a LOCK TABLE a; LOCK TABLE b;. As tabelas são bloqueadas uma a uma na ordem especificada no comando LOCK.
modo_de_bloqueio
O modo de bloqueio especifica os bloqueios com os quais este modo conflita. Os modos de bloqueio estão descritos na Seção 12.3 . Se não for especificado nenhum modo de bloqueio, então ACCESS EXCLUSIVE, o modo mais restritivo, é usado.

Observações

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 tão logo a transação termina. Um comando LOCK aparecendo fora de um bloco de transação forma uma transação autocontida e, portanto, o bloqueio é liberado logo após ser obtido.

O comando LOCK TABLE trata somente de bloqueios no nível de tabela e, portanto, os nomes dos modos contendo ROW são todos equivocados. Os nomes destes modos devem ser lidos geralmente como indicando a intenção de obter um bloqueio no nível de linha dentro da tabela bloqueada. Também, o modo ROW EXCLUSIVE é um bloqueio de tabela compartilhável. Deve-se ter em mente que todos os modos de bloqueio possuem semântica idêntica no que diz respeito ao LOCK TABLE, diferindo apenas nas regras sobre quais modos conflitam com quais modos.

Exemplos

Obter 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 = 'Guerra Nas Estrelas - Episódio I - A Ameaça Fantasma';
-- Executar ROLLBACK se a linha não for encontrada
INSERT INTO filmes_comentarios_usuario 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_usuario WHERE id IN
    (SELECT id FROM filmes WHERE avaliacao < 5);
DELETE FROM filmes WHERE avaliacao < 5;
COMMIT WORK;

Compatibilidade

Não existe o comando LOCK TABLE no padrão SQL, 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 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.

SourceForge.net Logo