sql >> Databasteknik >  >> RDS >> Sqlserver

Vad blockerar Välj topp 1 * från TableName med (nolock) från att returnera ett resultat?

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


  1. Hur verifierar jag att sqlplus kan ansluta?

  2. Laravel 5 använder ELLER tillstånd med BETWEEN

  3. Autoinkrementera ett fält tills ett visst villkor är uppfyllt mysql

  4. VS 2019 och MySQL Entity Framework dubblerar databasnamn