sql >> Database >  >> RDS >> Sqlserver

Essentials en gebruik van NOLOCK-hint in SQL Server

Het belangrijkste idee van het SQL Server-vergrendelingsmechanisme is dat het de consistentie van transacties controleert. Volgens dit principe vergrendelt SQL Server-engine de rij of rijen als een proces invoeg-, verwijder- of updatebewerkingen wil uitvoeren en staat geen ander proces toe totdat de transactie is voltooid. Onder bepaalde omstandigheden kan dit vergrendelingsmechanisme leiden tot prestatieproblemen zoals hoge gelijktijdige procesdrukken. U kunt dus de impasse (deadlock is een gelijktijdigheidsprobleem waarbij twee transacties tegelijkertijd toegang willen hebben tot dezelfde gegevens) problemen in uw database ervaren. In dit artikel zullen we ons concentreren op het voorkomen van vergrendelingsproblemen met behulp van de NOLOCK-hint. Laten we eerst de belangrijkste essenties en details van de vuile leesmethodologie leren, omdat de NOLOCK-hint vuile lezing kan veroorzaken.

Dirty Read: In deze leesmethodologie leest het leesproces niet-vastgelegde gegevens en geeft het leesproces niet om open transacties, dus de vergrendelingen leiden niet tot problemen in het leesproces. Als gevolg hiervan vermindert dit type uitlezing de vergrendelingsproblemen. De methode voor vuil lezen heeft echter voor- en nadelen, omdat vuil lezen inconsistentieproblemen kan veroorzaken in de resultatenset van de SELECT-instructie. Zoals reeds opgemerkt, kunnen deze resultatensets niet-vastgelegde transactiegegevens bevatten, daarom moeten we rekening houden met de vuile lezing bij het besluit om dit soort lezing te doen. We kunnen niet zeker zijn van de nauwkeurigheid van de rijen die we maken tijdens het lezen, omdat deze rijen kunnen worden teruggedraaid. Aan de andere kant stelt dit type lezen ons in staat vergrendelingsproblemen te voorkomen en de prestaties van SQL Server te verbeteren.

NOLOCK: Het standaard isolatieniveau van SQL Server is Read Committed en in dit isolatieniveau staat SQL Server niet toe om vergrendelde objecten te lezen die zijn vergrendeld door niet-vastgelegde transacties. Bovendien kunnen deze vergrendelde objecten worden gewijzigd volgens de escalatie van de vergrendeling.

Opmerking:in dit artikel over het hoofdconcept van SQL Server-vergrendeling vindt u details over vergrendeling en escalatie van vergrendelingen.

Stel je voor dat je twee databasegebruikers hebt en deze gebruikers willen een update- en selectiebewerking voor de database uitvoeren. Een eerste gebruiker begint een bepaalde rij in de tabel bij te werken en vervolgens wil de andere gebruiker dezelfde rij lezen. Deze twee gebruikers voeren de volgende update- en selectie-instructies uit, die wordt geïllustreerd in de onderstaande afbeelding.

In dit geval wacht gebruiker2 minstens 10 seconden, waarna de transactie wordt teruggedraaid door gebruiker1 en vervolgens gebruiker2 kan de groene rij lezen omdat de vergrendelde rij wordt vrijgegeven door gebruiker1. Dit is het standaardgedrag van het SQL Server Read Committed-isolatieniveau.

Nu zullen we dit geval demonstreren in SQL Server. Allereerst zullen we de FruitSales-tabel en de bijbehorende rijen maken.

TABEL MAKEN FruitSales(Id INT IDENTITY (1,1) PRIMAIRE SLEUTEL, [Name] Varchar(20) ,SalesTotal Float)GOINSERT INTO FruitSales VALUES('Apple',10) ,('Orange',8), ( 'Banaan',2)

In deze stap zullen we twee SQL Server Management Studio-queryvensters openen en de user1-query uitvoeren en vervolgens de user2-query uitvoeren.

 ---USER1----BEGIN TRAN-UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 WACHTVOOR VERTRAGING '00:00:10'ROLLBACK TRANSACTIE ---USER2----STEL STATISTIEKEN TIJD IN ONSELECT * VANUIT FruitSales WAAR ID=2

Zoals je kunt zien in de bovenstaande afbeelding, wacht de tweede vraag tot het terugdraaien van de gebruiker1-transactie.

Nu zullen we de NOLOCK-hint en gebruiksdetails bespreken. De NOLOCK-hint is de meest populaire tabelhint die wordt gebruikt door databaseontwikkelaars en -beheerders om vergrendelingsproblemen in SQL Server-databases te elimineren. Met behulp van de NOLOCK-tabelhint kunnen we vergrendelde objecten (rij, pagina of tabel) lezen die zijn vergrendeld door open transacties. De NOLOCK-hint overschrijft het standaardgedrag van de SQL Server-queryoptimalisatie, zodat de select-instructie de vergrendelde objecten kan lezen.

Nu zullen we de NOLOCK-hint toevoegen aan de user2 select-instructie en vervolgens de user1-update starten en vervolgens de user2 select-instructie uitvoeren.

---USER1----BEGIN TRAN-UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 WACHTVOOR VERTRAGING '00:00:10'ROLLBACK TRANSACTIE ---USER2----STEL STATISTIEKEN IN TIJD ONSELECT * VAN FruitSales MET (NOLOCK) WHERE Id=2

In deze stap zullen we uitleggen hoe u de NOLOCK-hint op de user2 select-instructie kunt beïnvloeden. Gebruiker1 voert de bijgewerkte instructie uit in een expliciete transactie en vervolgens voert gebruiker2 de select-instructie uit en de resultaatset retourneert zonder vertraging de voltooiing van de transactie. Dit is het hoofdidee van NOLOCK, het leest vergrendelde objecten.

Nu zullen we ons concentreren op de resultatenset van de select-instructie. De user2 select-instructie heeft de SalesTotal-waarde 20 opgehaald, maar de werkelijke waarde van SalesTotal is nog steeds 8. Houd er rekening mee dat als u de NOLOCK-tabelhint in uw select-instructie gebruikt, u dit soort onnauwkeurige gegevensresultaten kunt tegenkomen.

Tip: Het sleutelwoord "WITH" is een verouderde functie, dus Microsoft raadt aan om het niet te gebruiken in uw nieuwe databaseontwikkeling en het sleutelwoord "WITH" in uw huidige ontwikkelingen te verwijderen. U kunt het gebruik van de NOLOCK-hint vinden zonder het trefwoord "WITH".

---USER1----BEGIN TRAN-UPDATE FruitSales SET SalesTotal =20 WHERE Id=2 WACHTFOR DELAY '00:00:10'ROLLBACK TRANSACTIESELECTEER * VAN FruitSales WHERE Id=2 --USER2---SELECT * FROM FruitSales (NOLOCK) WHERE Id=2

Bovendien is de READUNCOMMITTED-tabelhint gelijk aan de NOLOCK-hint en kunnen we de READUNCOMMITTED-hint gebruiken in plaats van de NOLOCK-hint.

SELECTEER * VAN FruitSales (READUNCOMMITTED) WHERE Id=2

Toch is er een specifiek geval over de NOLOCK-hint die de vergrendelingsbarrière niet kan passeren. Als er een proces is dat een tabel wijzigt, kan de NOLOCK-hint dit type vergrendeling niet overwinnen en kan de leesbewerking niet doorgaan. De reden voor dit probleem is dat de NOLOCK-hint de Sch-S-vergrendeling (schemastabiliteit) verwerft en de ALTER TABLE-instructie de SCH-M-vergrendeling (schemawijziging), zodat er een conflict optreedt.

Eerst zullen we de Object_Id van FruitSales-tabel leren met behulp van de volgende query.

selecteer OBJECT_ID('FruitSales')

Voer de volgende user1-query uit en voer vervolgens de user2-query uit. Als gevolg hiervan vertraagt ​​de user2-query de voltooiing van het user1-tabelwijzigingsproces.

--USER1---BEGIN TRANALTERTABEL FruitSalesADD ColorofFruit varchar(200) WACHTVOOR VERTRAGING '00:00:35GOCOMMIT TRAN --USER2---SELECT * VAN FruitSales (NOLOCK) WAAR Id=2

Open het nieuwe queryvenster en voer de volgende query uit. Deze zoekopdracht helpt om het vergrendelingstype van de zoekopdrachten gebruiker1 en gebruiker2 te achterhalen.

SELECT Resource_type, Resource_database_id, Resource_description, Resource_associated_entity_id, Resource_lock_partition, Request_mode, Request_type, Request_status, Request_session_id, Request_request_id, Request_owner_type, Request_owner_id, Lock_owner_addressFROM sys.dm_tran_lockswhere resource_pre> 

Nu zullen we de compatibiliteitsmatrix voor SCH-M en SCH-S bekijken. De matrix beschrijft dat SCH-M en SCH-S interactie een conflict veroorzaakt.

Conclusie

In dit artikel noemden we het vuile leesproces en de NOLOCK-hint. Het gebruik van de NOLOCK-hint is een effectieve methode om een ​​vergrendelde pagina te lezen, maar het heeft ook enkele voor- en nadelen. Om deze reden moet u de NOLOCK-hint overwegen voordat u deze gebruikt.

Referenties

Handleiding voor SQL Server-transactievergrendeling en rijversies

Tips (Transact-SQL) – Tabel

ISOLATIENIVEAU VAN TRANSACTIE INSTELLEN (Transact-SQL)


  1. INSERT ... OP DUPLICATE KEY UPDATE met WAAR?

  2. Dynamische SQL (EXECUTE) als voorwaarde voor IF-statement

  3. Hoe dubbelzinnige kolomnamen op te lossen bij het ophalen van resultaten?

  4. Hoe REVERSE() werkt in MariaDB