Editar: como señala @MaxVernon , lo siguiente no es una sugerencia para usar NOLOCK , y muy bien debería haber mencionado establecer el nivel de transacción READ UNCOMMITED
y dejar que la connotación negativa permanezca allí en lugar de NOLOCK
aparecer en primer lugar. Entonces, como se publicó originalmente:
La respuesta rápida y simple es "Sí, la primera consulta bloqueará la segunda consulta a menos que se especifique una pista de índice específica ( NOLOCK , a veces llamada" lectura sucia ") o el nivel de aislamiento de transacción de la segunda consulta se establece en READ UNCOMMITED
(que opera de manera idéntica), No, no lo hace."
En respuesta al detalle adicional proporcionado en la pregunta que implica la inclusión de una WITH
cláusula sobre la segunda SELECT
, que es mutuamente excluyente o no, las interacciones entre las dos consultas serán en gran medida las mismas.
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'Foo'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.Foo;
CREATE TABLE dbo.Foo
(
Foo_PK BIGINT IDENTITY( 1, 1 ) NOT NULL,
PRIMARY KEY ( Foo_PK ),
Bar BIT,
x BIT,
y BIT,
z BIT
);
CREATE NONCLUSTERED INDEX IX_Foo_x
ON dbo.Foo ( x );
INSERT INTO dbo.Foo ( Bar, x, y, z )
VALUES ( 1, 1, 1, 1 ), ( 0, 0, 0, 0 );
END;
GO
BEGIN TRANSACTION;
UPDATE dbo.Foo
SET y = 0
WHERE x = 1;
-- COMMIT TRANSACTION;
En una sesión separada, ejecute lo siguiente:
SELECT *
FROM dbo.Foo WITH ( NOLOCK );
GO
SELECT *
FROM dbo.Foo;
Puede examinar los bloqueos que se están ejecutando actualmente sp_lock
, preferiblemente en otra sesión separada:
EXECUTE dbo.sp_lock;
Debería ver un KEY
bloqueo de tipo retenido por el spid que realiza la transacción de inserción en modo X
(exclusivo), que no debe confundirse con los otros IX
bloqueos (Intent-Exclusive). La documentación del bloqueo indica que, si bien el KEY
bloqueo es específico del rango, también evita que otras transacciones inserten o actualicen las columnas afectadas al alterar los datos contenidos en el mismo para que pueda caer dentro de ese rango de la consulta original. Como el bloqueo en sí es exclusivo, la primera consulta impide el acceso al recurso desde cualquier otra transacción concurrente. En efecto, todas las filas de la columna están bloqueadas, estén o no dentro del rango especificado por la primera consulta.
El S
bloqueo retenido por la segunda sesión se mantendrá así WAIT
hasta que se X
libere el bloqueo, evitando que se tome otro X
(o U
) bloqueo en ese recurso desde un spid concurrente diferente antes de que la segunda sesión complete su operación de lectura, justificando la existencia del S
bloqueo.
Ahora una edición para mayor claridad: a menos que me equivoque en lo que es una lectura sucia de la breve descripción de los riesgos mencionados aquí ... Edición 3 : Acabo de darme cuenta de que no estoy considerando el efecto de un punto de verificación de antecedentes que escribe un de transacciones aún no confirmadas en disco, así que sí, mi explicación fue engañosa.
En la segunda consulta, el primer lote puede (y en este caso) devolverá datos no confirmados. El segundo lote, que se ejecuta en el nivel de aislamiento de transacción predeterminado READ COMMITED
, regresará solo después de que se haya completado una confirmación o reversión en la primera sesión.
Desde aquí puede ver sus planes de consulta y los niveles de bloqueo asociados, pero mejor aún, puede leer todo acerca de los bloqueos en SQL Server aquí .
SELECT * FROM Table1
si eso es exactamente lo que necesito?