Supongamos que tengo la siguiente consulta de larga duración
UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows
y supongamos que la siguiente consulta se ejecuta mientras se ejecuta la consulta anterior
SELECT *
FROM [Table1]
¿La primera consulta evita que la segunda consulta se ejecute hasta que se complete la primera consulta? Si es así, ¿la primera consulta evita que la segunda consulta se ejecute en todas las filas o solo en las filas involucradas en la cláusula WHERE?
EDITAR:
Supongamos que la segunda consulta es
SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
-- the clause in the first query and which has additional matching elements
fuente
SELECT * FROM Table1
si eso es exactamente lo que necesito?*
Por sí solo es una mala práctica porque cuando la estructura de la tabla cambia, la aplicación generalmente se rompe (en el resultado aparecen columnas inesperadas).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 deNOLOCK
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 segundaSELECT
, que es mutuamente excluyente o no, las interacciones entre las dos consultas serán en gran medida las mismas.En una sesión separada, ejecute lo siguiente:
Puede examinar los bloqueos que se están ejecutando actualmente
sp_lock
, preferiblemente en otra sesión separada:Debería ver un
KEY
bloqueo de tipo retenido por el spid que realiza la transacción de inserción en modoX
(exclusivo), que no debe confundirse con los otrosIX
bloqueos (Intent-Exclusive). La documentación del bloqueo indica que, si bien elKEY
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 seX
libere el bloqueo, evitando que se tome otroX
(oU
) 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 delS
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í .
fuente
WITH (NOLOCK)
sería útil en este caso. Visite brentozar.com/archive/2011/11/… y brentozar.com/archive/2013/02/… para obtener más información.WITH (NOLOCK)
sugerencia no devuelve páginas sucias de la memoria que no se han confirmado. En realidad, lee las filas de la tabla (ya sea en el disco o en la memoria caché) sin bloquear que los escritores actualicen o agreguen filas a las páginas que usa la tabla.