sql >> Base de Datos >  >> RDS >> Sqlserver

Fundamentos y uso de la sugerencia NOLOCK en SQL Server

La idea principal del mecanismo de bloqueo de SQL Server es que controla la consistencia de las transacciones. De acuerdo con este principio, si un proceso desea realizar operaciones de inserción, eliminación o actualización, el motor de SQL Server bloquea la fila o filas y no permite otro proceso hasta que se complete la transacción. En algunas circunstancias, este mecanismo de bloqueo puede provocar problemas de rendimiento, como altas presiones de proceso concurrentes. Por lo tanto, puede experimentar los problemas de punto muerto (el punto muerto es un problema de concurrencia en el que dos transacciones desean acceder a los mismos datos simultáneamente) en su base de datos. En este artículo, nos centraremos en cómo evitar problemas de bloqueo con la ayuda de la sugerencia de NOLOCK. Primero, aprendamos los principales elementos esenciales y los detalles de la metodología de lectura sucia porque la sugerencia de NOLOCK puede causar una lectura sucia.

Lectura sucia: En esta metodología de lectura, el proceso de lectura lee datos no confirmados y no se preocupa por las transacciones abiertas, por lo que los bloqueos no generan ningún problema en el proceso de lectura. Como resultado, este tipo de lectura reduce los problemas de bloqueo. Sin embargo, la metodología de lectura sucia tiene ventajas y desventajas porque la lectura sucia puede causar problemas de incoherencia en el conjunto de resultados de la instrucción SELECT. Como ya se señaló, estos conjuntos de resultados pueden incluir datos de transacciones no comprometidas, por lo que debemos considerar la lectura sucia al decidir realizar este tipo de lectura. No podemos estar seguros de la precisión de las filas que hacemos durante la lectura sucia porque estas filas se pueden revertir. Por otro lado, este tipo de lectura nos permite evitar problemas de bloqueo y aumentar el rendimiento de SQL Server.

NOLOCK: El nivel de aislamiento predeterminado de SQL Server es Lectura confirmada y, en este nivel de aislamiento, SQL Server no permite leer objetos bloqueados que están bloqueados por transacciones no confirmadas. Además, estos objetos bloqueados se pueden cambiar de acuerdo con la escalada de bloqueo.

Nota:En este artículo sobre el concepto principal de bloqueo de SQL Server, puede encontrar detalles sobre el bloqueo y la escalada de bloqueo.

Imagine que tiene dos usuarios de la base de datos y estos usuarios desean ejecutar la operación de actualización y selección en la base de datos. Un primer usuario comienza a actualizar una fila en particular en la tabla y luego el otro usuario quiere leer la misma fila. Estos dos usuarios ejecutan las siguientes declaraciones de actualización y selección, que se ilustran en la siguiente imagen.

En este caso, el usuario2 espera al menos 10 segundos y luego el usuario1 revertirá la transacción, y luego usuario2 puede leer la fila verde porque la fila bloqueada será liberada por usuario1. Este es el comportamiento predeterminado del nivel de aislamiento de lectura confirmada de SQL Server.

Ahora, demostraremos este caso en SQL Server. En primer lugar, crearemos la tabla FruitSales y sus filas.

CREATE TABLE FruitSales
(Id INT IDENTITY (1,1)  PRIMARY KEY, [Name] Varchar(20) ,
SalesTotal Float)
GO

INSERT INTO FruitSales VALUES
('Apple',10) ,('Orange',8), ('Banana',2)

En este paso, abriremos dos ventanas de consulta de SQL Server Management Studio y ejecutaremos la consulta de usuario1 y luego ejecutaremos la consulta de usuario2.

	  ---USER1----

BEGIN TRAN 
UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 
WAITFOR DELAY '00:00:10'
ROLLBACK TRANSACTION

	---USER2----
SET STATISTICS TIME ON
SELECT * FROM FruitSales WHERE Id=2

Como puede ver en la imagen de arriba, la segunda consulta espera hasta la reversión de la transacción del usuario1.

Ahora, discutiremos la sugerencia de NOLOCK y los detalles de uso. La sugerencia NOLOCK es la sugerencia de tabla más popular que utilizan los desarrolladores y administradores de bases de datos para eliminar los problemas de bloqueo en las bases de datos de SQL Server. Con la ayuda de la sugerencia de tabla NOLOCK, podemos leer objetos bloqueados (fila, página o tabla) que están bloqueados por transacciones abiertas. La sugerencia NOLOCK anula el comportamiento predeterminado del optimizador de consultas de SQL Server para que la declaración de selección pueda leer los objetos bloqueados.

Ahora, agregaremos la sugerencia NOLOCK a la declaración de selección de usuario2 y luego iniciaremos la actualización de usuario1 y luego ejecutaremos la declaración de selección de usuario2.

---USER1----

BEGIN TRAN 
UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 
WAITFOR DELAY '00:00:10'
ROLLBACK TRANSACTION

			---USER2----
SET STATISTICS TIME ON
SELECT * FROM FruitSales WITH(NOLOCK) WHERE Id=2

En este paso, explicaremos cómo afectar la sugerencia de NOLOCK en la declaración de selección de usuario2. El usuario1 ejecuta la declaración actualizada en una transacción explícita y luego el usuario2 ejecuta la declaración de selección y el conjunto de resultados devuelve sin demora la finalización de la transacción. Esta es la idea principal de NOLOCK, lee objetos bloqueados.

Ahora, nos centraremos en el conjunto de resultados de la declaración de selección. La declaración de selección de usuario2 recuperó el valor SalesTotal 20 pero el valor real de SalesTotal sigue siendo 8. Tenga en cuenta que si está utilizando la sugerencia de tabla NOLOCK en su declaración de selección, es posible que se enfrente a este tipo de resultados de datos inexactos.

Consejo: La palabra clave "CON" es una función obsoleta, por lo que Microsoft recomienda no usarla en el desarrollo de su nueva base de datos y eliminar la palabra clave "CON" en sus desarrollos actuales. Puede encontrar el uso de la sugerencia NOLOCK sin la palabra clave "CON".

---USER1----
BEGIN TRAN 
UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 
WAITFOR DELAY '00:00:10'
ROLLBACK TRANSACTION
SELECT * FROM FruitSales WHERE Id=2

   --USER2---
SELECT * FROM FruitSales (NOLOCK) WHERE Id=2

Además, la sugerencia de tabla READUNCOMMITTED es equivalente a la sugerencia NOLOCK y podemos usar la sugerencia READUNCOMMITTED en lugar de la sugerencia NOLOCK.

SELECT * FROM FruitSales (READUNCOMMITTED) WHERE Id=2

Aun así, hay un caso particular sobre la pista NOLOCK que no puede pasar la barrera de bloqueo. Si hay algún proceso que altere una tabla, la sugerencia NOLOCK no puede superar este tipo de bloqueo y no puede continuar con la operación de lectura. El motivo de este problema es que la sugerencia NOLOCK adquiere el bloqueo Sch-S (estabilidad del esquema) y la instrucción ALTER TABLE adquiere el bloqueo SCH-M (modificación del esquema), por lo que se produce un conflicto.

Primero, aprenderemos el Object_Id de la tabla FruitSales con la ayuda de la siguiente consulta.

select OBJECT_ID('FruitSales')

Ejecute la siguiente consulta de usuario1 y luego ejecute la consulta de usuario2. Como resultado, la consulta de usuario2 retrasará la finalización del proceso de modificación de la tabla de usuario1.

--USER1---
BEGIN TRAN
ALTER TABLE FruitSales
ADD ColorofFruit varchar(200) 
WAITFOR DELAY '00:00:35
GO
COMMIT TRAN

   --USER2---
SELECT * FROM FruitSales (NOLOCK) WHERE Id=2

Abra la nueva ventana de consulta y ejecute la siguiente consulta. Esta consulta ayudará a averiguar el tipo de bloqueo de las consultas usuario1 y usuario2.

SELECT Resource_type,
	 Resource_database_id,
	 Resource_description,
	 Resource_associated_entity_id,
	 Resource_lock_partition,
	 Request_mode,
	 Request_type,
	 Request_status,
	 Request_session_id,
	 Request_request_id,
	 Request_owner_type,
	 Request_owner_id,
	 Lock_owner_address
FROM sys.dm_tran_locks
where resource_associated_entity_id =647673355

Ahora, revisaremos la matriz de compatibilidad de bloqueo para la interacción SCH-M y SCH-S. La matriz describe que la interacción SCH-M y SCH-S provoca un conflicto.

Conclusión

En este artículo, mencionamos el proceso de lectura sucia y la sugerencia de NOLOCK. El uso de la sugerencia NOLOCK es un método eficaz para leer una página bloqueada, pero también tiene algunas ventajas y desventajas. Por esta razón, debe considerar la sugerencia de NOLOCK antes de usarla.

Referencias

Guía de control de versiones de filas y bloqueo de transacciones de SQL Server

Sugerencias (Transact-SQL) – Tabla

ESTABLECER NIVEL DE AISLAMIENTO DE TRANSACCIONES (Transact-SQL)