Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

O que está bloqueando Select top 1 * from TableName com (nolock) de retornar um resultado?


SELECT consultas com NOLOCK na verdade não aceitam cadeados, eles ainda precisam de um SCH-S (estabilidade de esquema) trava na mesa (e como é um heap também levará um hobt bloqueio ).

Além disso, antes do SELECT pode até começar o SQL Server deve compilar um plano para a instrução, que também exige que ele tome um SCH-S trancar na mesa.

Como sua transação de longa duração cria a tabela via SELECT ... INTO ele contém um SCH-M incompatível bloqueie-o até que a instrução seja concluída.

Você pode verificar isso olhando em sys.dm_os_waiting_tasks enquanto enquanto durante o período de bloqueio.

Quando tentei o seguinte em uma conexão
BEGIN TRAN

SELECT *
INTO NewT
FROM master..spt_values

/*Remember to rollback/commit this later*/

E então executando (ou simplesmente tentando visualizar o plano de execução estimado)
SELECT *
FROM NewT
WITH (NOLOCK)

em um segundo a consulta de leitura foi bloqueada.
SELECT wait_type,
       resource_description
FROM sys.dm_os_waiting_tasks
WHERE session_id = <spid_of_waiting_task>

Mostra que o tipo de espera é realmente SCH_S e o recurso de bloqueio 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