LOCK

Nombre

LOCK  --  Explícitamente bloquea una tabla dentro de una transacción

Synopsis

LOCK [ TABLE ] name
LOCK [ TABLE ] name IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE
LOCK [ TABLE ] name IN SHARE ROW EXCLUSIVE MODE
  

Entradas

name

El nombre de una tabla existente para bloquear.

ACCESS SHARE MODE

Nota

A este modo de bloqueo se accede automáticamente sobre tablas que estan siendo consultadas. Postgres libera automáticamente los bloqueos accedidos ACCESS SHARE despues de que se haya hecho la sentencia.

Este es el modo de bloqueo menos restrictivo el cual entra en conflicto sólo con el modo ACCESS EXCLUSIVE . Se pretende proteger una tabla que está siendo consultada de sentencias concurrentes ALTER TABLE, DROP TABLE y VACUUM sobre la misma tabla.

ROW SHARE MODE

Nota

Se accede automáticamente por cualquier declaración SELECT FOR UPDATE.

Conflictos con los modos de bloqueo EXCLUSIVE y ACCESS EXCLUSIVE.

ROW EXCLUSIVE MODE

Nota

Se accede automáticamente por cualquier sentencia UPDATE, DELETE, INSERT.

Conflictos con los modos SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE ACCESS EXCLUSIVE. Generalmente significa que una transacción actualiza o inserta algunas tuplas en una tabla.

SHARE MODE

Nota

Se accede automáticamente por cualquier sentencia CREATE INDEX

Conflictos con los modos ROW EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE y ACCESS EXCLUSIVE . Este modo protege una tabla contra actualizaciones concurrentes.

SHARE ROW EXCLUSIVE MODE

Conflictos con los modos ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE y ACCESS EXCLUSIVE. Este modo es más restrictivo que el modo SHARE debido a que sólo puede soportar este bloqueo una transacción por vez .

EXCLUSIVE MODE

Conflictos con los modos ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE y ACCESS EXCLUSIVE modes. Este modo es aún más restrictivo que ése de SHARE ROW EXCLUSIVE; bloquea todas las consultas concurrentes SELECT FOR UPDATE .

ACCESS EXCLUSIVE MODE

Nota

Se accede automáticamente por las sentencias ALTER TABLE, DROP TABLE, VACUUM .

Este es el modo de bloqueo más restrictivo y es incompatible con todos los demás modos de bloqueo y protege una tabla bloqueada de cualquier otra operación concurrente.

Nota

Este modo de bloqueo se accede también por un LOCK TABLE sin cualificar. (i.e. el comando sin una opción de bloqueo explícita).

Salidas

LOCK TABLE

El bloqueo se activó con éxito.

ERROR name: La tabla no existe.

Mensaje devuelto si el nombre no existe.

Description

Postgres siempre usa el modo de bloqueo menos restrictivo cuando le es posible. LOCK TABLE toma medidas para cuando se pueda necesitar un modo de bloqueo mas restrictivo.

Por ejemplo, una aplicación ejecuta una transacción en el nivel de aislamiento READ COMMITTED y necesita asegurar la existencia de datos en una tabla para la duracion de la transacción. Para ello tú podrías usar el modo de bloqueo SHARE sobre la tabla antes de la consulta. Esto protegerá los datos de cambios concurrentes y proporcionará cualquier otra operación de escritura sobre la tabla con datos en su verdadero estado actual, porque el modo de bloqueo SHARE es incompatible con cualquier ROW EXCLUSIVE accedido por los que esriben, y LOCK TABLE "tabla" en sentencia IN SHARE MODE esperará hasta que se produzca o se "baje" cualquier operación de escritura concurrente.

Nota

Para leer datos en su verdadero estado actual cuando ejecutas una transacción en el nivel de aislamiento SERIALIZABLE tienes que ejecutar una declaración LOCK TABLE antes de la ejecución de cualquier sentencia DML, cuando la transacción define qué cambios concurrentes serán visibles por ellos mismos.

Además de los requerimientos precedentes, si una transacción va a cambiar datos en una tabla entonces se debería acceder al modo SHARE ROW EXCLUSIVE para evitar condiciones de punto muerto cuando dos transacciones coincidentes intentan bloquear la tabla en modo SHARE y entonces intentan cambiar datos en esta tabla, ambas (implicitamente) accediendo al modo de bloqueo ROW EXCLUSIVE que es incompatible con el bloqueo SHARE .

Para continuar con los puntos muertos (cuando dos transacciones se esperan la una a la otra) tema tratado arriba, deberías seguir dos reglas generales para evitar condiciones de punto muerto :

Nota

Postgres no detecta puntos muertos "bajará" una transacción a la espera para resolver el punto muerto.

Notas

LOCK es una extension del lenguaje Postgres.

Excepto para los modos de bloqueo ACCESS SHARE/EXCLUSIVE , todos los demás modos de bloqueo de Postgres y las sentencias LOCK TABLE son compatibles con aquellos presentes en Oracle.

LOCK funciona sólo dentro de transacciones.

Uso

Illustrate a SHARE lock on a primary key table when going to perform inserts into a foreign key table:

BEGIN WORK;
LOCK TABLE películas IN SHARE MODE;
SELECT id FROM películas
    WHERE name = 'Star Wars: Episodio I - La amenaza fantasma';
-- Haz ROLLBACK si el registro no fue devuelto
INSERT INTO comentarios_usuario_películas VALUES
    (_id_, 'GUAY! Llevaba tanto tiempo esperándola!');
COMMIT WORK;
   

Toma un bloqueo SHARE ROW EXCLUSIVE clave de tabla primaria cuando vayas a hacer una operación de borrado:

BEGIN WORK;
LOCK TABLE películas IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM comentarios_usuario_películas WHERE id IN
    (SELECT id FROM películas WHERE clasificación < 5);
DELETE FROM películas WHERE clasificación < 5;
COMMIT WORK;
   

Compatibilidad

SQL92

No hay LOCK TABLE en SQL92, que usa en cambio SET TRANSACTION para especificar niveles de concurrencia en transacciones. Nosotros también la tenemos; ver SET para más detalles.