Descripción del bloqueo

Completado

El Control de simultaneidad de varias versiones (MVCC) proporciona la configuración de simultaneidad adecuada para la mayoría de los escenarios. Sin embargo, si una aplicación requiere bloqueos específicos que controlan exactamente qué filas se ven afectadas y con un nivel de bloqueo específico, los modos de bloqueo explícitos habilitan este control específico.

En Azure Database for PostgreSQL, hay tres tipos de bloqueo explícito: de nivel de tabla, de nivel de fila y de nivel de página. La transacción inicial solicita un bloqueo y, si se acepta, el bloqueo solicitado se convierte en el bloqueo existente. Si otra transacción intenta sacar un bloqueo en los mismos datos, se concede el bloqueo si no entra en conflicto con la transacción original.

Por ejemplo, dos transacciones pueden consultar los mismos datos al mismo tiempo con una instrucción SELECT. Estas solicitudes usarían un bloqueo ACCESS SHARE y ambos se permitirían. En otro escenario, una transacción consulta datos con una instrucción SELECT y un bloqueo ACCESS SHARE, pero al mismo tiempo otra transacción intenta quitar la misma tabla. Quitar una tabla requiere un bloqueo ACCESS EXCLUSIVE, que no se concedería, en este escenario.

Bloqueos de tabla

Los bloqueos de nivel de tabla adquieren bloqueos en toda una tabla, incluso si incluyen ROW en su nombre. Es posible que sea necesario bloquear una tabla completa si se está modificando la propia tabla, o podría ser más eficaz que quitar muchos bloqueos de nivel de fila.

Hay ocho tipos de bloqueo de nivel de tabla en Azure Database for PostgreSQL y los comandos SQL que adquieren estos tipos de bloqueos son:

Modo de bloqueo Adquirido por
ACCESS SHARE Comando SELECT
ROW SHARE Comandos SELECT FOR UPDATE y SELECT FOR SHARE
ROW EXCLUSIVE Comandos UPDATE, DELETE e INSERT
SHARE UPDATE EXCLUSIVE Comandos ANALYZE, CREATE INDEX CONCURRENTLY, CREATE STATISTICS, COMMENT ON y REINDEX CONCURRENTLY, algunos comandos ALTER INDEX y ALTER TABLE, y VACUUM (no FULL)
COMPARTIR Comando CREATE INDEX (no CONCURRENTLY)
SHARE ROW EXCLUSIVE Comando CREATE TRIGGER y algunos comandos ALTER TABLE
EXCLUSIVE Comando REFRESH MATERIALIZED VIEW CONCURRENTLY
ACCESS EXCLUSIVE Comandos DROP TABLE, REINDEX, TRUNCATE, CLUSTER, REFRESH MATERIALIZED VIEW (no CONCURRENTLY), la mayoría de los comandos ALTER INDEX y ALTER TABLE, y VACUUM FULL

Cada tipo de bloqueo existente bloquea otros bloqueos solicitados que se adquieren. En la tabla siguiente se muestra qué bloqueos bloquean la adquisición de otros:

-- ACCESS SHARE existente ROW SHARE existente ROW EXCLUSIVE existente SHARE UPDATE EXCLUSIVE existente SHARE existente SHARE ROW EXCL existente EXCLUSIVE existente ACCESS EXCLUSIVE existente
ACCESS SHARE solicitado Bloqueado
ROW SHARE solicitado Bloqueado Bloqueado
ROW EXCLUSIVE solicitado Bloqueado Bloqueado Bloqueado Bloqueado
SHARE UPDATE EXCLUSIVE solicitado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado
SHARE solicitado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado
SHARE ROW EXCLUSIVE solicitado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado
EXCLUSIVE solicitado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado
ACCESS EXCLUSIVE solicitado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado Bloqueado

Bloqueos de nivel de fila

Los bloqueos de nivel de fila son más granulares y solo afectan a otra transacción que accede a la misma fila. Este tipo de bloqueo mejora la simultaneidad, pero la adquisición y eliminación de muchos bloqueos afecta negativamente al rendimiento. PostgreSQL adquiere automáticamente los bloqueos de nivel de fila; no se aplican manualmente.

Hay cuatro tipos de bloqueo de nivel de fila en Azure Database for PostgreSQL y se adquieren en función de qué otros tipos de bloqueo deben bloquearse:

-- FOR KEY SHARE existente FOR SHARE existente FOR NO KEY UPDATE existente FOR UPDATE existente
FOR KEY SHARE solicitado Bloqueado
FOR SHARE solicitado Bloqueado Bloqueado
FOR NO KEY UPDATE solicitado Bloqueado Bloqueado Bloqueado
FOR UPDATE solicitado Bloqueado Bloqueado Bloqueado Bloqueado

Bloqueos de nivel de página

Los bloqueos de nivel de página afectan a una página de datos, que normalmente consta de varias filas. Aunque los procesos de PostgreSQL usan bloqueos de nivel de página, los desarrolladores de aplicaciones normalmente no requieren este tipo de bloqueo.

Aplicación manual de bloqueos y visualización de los bloqueos actuales

Para aplicar manualmente un bloqueo de nivel de tabla, puede usar el comando LOCK con el modo de bloqueo necesario. El comando LOCK debe estar dentro de una transacción. Los bloqueos se liberan cuando se completa la transacción. Por ejemplo:

BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;

Para ver los bloqueos que se aplican actualmente en la base de datos, use pg_locks. Por ejemplo, para ver todos los bloqueos actuales, use el comando siguiente:

SELECT * FROM pg_locks;