SELECT
frågor med NOLOCK
ta faktiskt inte några lås, de behöver fortfarande en SCH-S
(schemastabilitet) lås på bordet (och eftersom det är en heap det kommer också att ta en hobt
lås
).
Dessutom före SELECT
kan till och med börja SQL Server måste kompilera en plan för satsen, vilket också kräver att den tar en SCH-S
låsa ute på bordet.
Eftersom din långa transaktion skapar tabellen via SELECT ... INTO
den innehåller en inkompatibel SCH-M
lås på den tills uttalandet slutförs.
Du kan verifiera detta genom att titta i sys.dm_os_waiting_tasks
medan medan under blockeringsperioden.
När jag provade följande i en anslutning
BEGIN TRAN
SELECT *
INTO NewT
FROM master..spt_values
/*Remember to rollback/commit this later*/
Och sedan exekvera (eller helt enkelt försöka se den beräknade genomförandeplanen)
SELECT *
FROM NewT
WITH (NOLOCK)
på en sekund blockerades läsfrågan.
SELECT wait_type,
resource_description
FROM sys.dm_os_waiting_tasks
WHERE session_id = <spid_of_waiting_task>
Visar att väntetypen verkligen är SCH_S
och blockeringsresursen 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