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

¿Qué impide que Select top 1 * de TableName con (nolock) devuelva un resultado?

SELECT consultas con NOLOCK en realidad no toman candados, todavía necesitan un SCH-S (estabilidad del esquema) bloqueo en la tabla (y como es un heap también tomará un hobt bloquear ).

Además antes de SELECT incluso puede comenzar SQL Server debe compilar un plan para la declaración, que también requiere que tome un SCH-S cerrar la mesa.

A medida que su transacción de larga ejecución crea la tabla a través de SELECT ... INTO contiene un SCH-M incompatible bloquearlo hasta que se complete la instrucción.

Puede verificar esto mirando en sys.dm_os_waiting_tasks mientras que mientras durante el período de bloqueo.

Cuando probé lo siguiente en una conexión

BEGIN TRAN

SELECT *
INTO NewT
FROM master..spt_values

/*Remember to rollback/commit this later*/

Y luego ejecutar (o simplemente intentar ver el plan de ejecución estimado)

SELECT *
FROM NewT
WITH (NOLOCK)

en un segundo se bloqueó la consulta de lectura.

SELECT wait_type,
       resource_description
FROM sys.dm_os_waiting_tasks
WHERE session_id = <spid_of_waiting_task>

Muestra que el tipo de espera es de hecho SCH_S y el recurso de bloqueo SCH-M

wait_type        resource_description
---------------- -------------------------------------------------------------------------------------------------------------------------------
LCK_M_SCH_S      objectlock lockPartition=0 objid=461960722 subresource=FULL dbid=1 id=lock4a8a540 mode=Sch-M associatedObjectId=461960722