sql >> Database teknologi >  >> RDS >> Sqlserver

Essentials og brug af NOLOCK tip i SQL Server

Hovedideen med SQL Server-låsemekanismen er, at den kontrollerer transaktionernes konsistens. Ifølge dette princip, hvis en proces ønsker at udføre indsættelses-, sletnings- eller opdateringsoperationer, låser SQL Server-motoren rækken eller rækkerne og tillader ikke en anden proces, før transaktionen er gennemført. Under nogle omstændigheder kan denne låsemekanisme føre til ydeevneproblemer såsom høje samtidige procestryk. Så du kan opleve deadlock (Deadlock er et samtidighedsproblem, hvor to transaktioner ønsker at få adgang til de samme data samtidigt) problemer i din database. I denne artikel vil vi fokusere på, hvordan du undgår låseproblemer ved hjælp af NOLOCK-tip. Lad os først lære de vigtigste essentielle og detaljer om beskidte læsemetoder, fordi NOLOCK-tipset kan forårsage beskidt læsning.

Snavset læsning: I denne læsemetodologi læser læseprocessen ikke-forpligtede data, og læseprocessen er ligeglad med åbne transaktioner, så låsene fører ikke til problemer i læseprocessen. Som følge heraf reducerer denne type aflæsning låseproblemerne. Men metoden med beskidt læsning har fordele og ulemper, fordi beskidt læsning kan forårsage inkonsistensproblemer i resultatsættet af SELECT-sætningen. Som allerede nævnt kan disse resultatsæt inkludere data om ikke-forpligtede transaktioner, det er derfor, vi skal overveje den beskidte læsning, når vi beslutter os for at foretage denne form for læsning. Vi kan ikke være sikre på nøjagtigheden af ​​rækker, som vi laver under beskidt læsning, fordi disse rækker kan rulles tilbage. På den anden side giver denne type læsning os mulighed for at undgå låseproblemer og øge ydelsen af ​​SQL Server.

NOLOCK: Standard isolationsniveauet for SQL Server er Read Committed, og på dette isolationsniveau tillader SQL Server ikke at læse låste objekter, som er låst af ikke-forpligtede transaktioner. Derudover kan disse låste objekter ændres i henhold til låseeskalering.

Bemærk:I denne artikel om hovedkoncept af SQL Server-låsning kan du finde detaljer om låsning og låseeskalering.

Forestil dig, at du har to databasebrugere, og disse brugere ønsker at udføre opdatering og vælge operation mod databasen. En første bruger begynder at opdatere en bestemt række i tabellen, og derefter vil den anden bruger læse den samme række. Disse to brugere udfører følgende opdatering og vælger sætninger, som er illustreret i billedet nedenfor.

I dette tilfælde venter bruger2 mindst 10 sekunder, og derefter vil transaktionen blive rullet tilbage af bruger1, og derefter bruger2 kan læse den grønne række, fordi den låste række frigives af bruger1. Dette er standardadfærden for SQL Server Read Committed isolationsniveauet.

Nu vil vi demonstrere denne sag i SQL Server. Først og fremmest vil vi oprette FruitSales-tabellen og dens rækker.

CREATE TABLE FrugtSalg(Id INT IDENTITET (1,1) PRIMÆR NØGLE, [Navn] Varchar(20) ,SalgTotal Float)GOINSERT INTO FruitSales VALUES('Apple',10) ,('Orange',8), ( 'Banan',2)

I dette trin vil vi åbne to SQL Server Management Studio-forespørgselsvinduer og udføre bruger1-forespørgslen og derefter udføre bruger2-forespørgslen.

 ---BRUGER1----BEGIN TRAN OPDATERING FrugtSalg SÆT SalgTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'TILBAGETRANSAKTION ---USER2----INDSTIL STATISTIK TID TIL VÆLG * FRA FruitSales HVOR Id=2

Som du kan se på billedet ovenfor, venter den anden forespørgsel indtil tilbagerulning af user1-transaktionen.

Nu vil vi diskutere NOLOCK-tip og brugsdetaljer. NOLOCK-tipset er det mest populære tabeltip, som bruges af databaseudviklere og administratorer til at eliminere låseproblemer i SQL Server-databaser. Ved hjælp af NOLOCK-tabeltipset kan vi læse låste objekter (række, side eller tabel), som er låst af åbne transaktioner. NOLOCK-tipset tilsidesætter standardadfærden for SQL Server-forespørgselsoptimering, så select-sætningen kan læse de låste objekter.

Nu vil vi tilføje NOLOCK-hintet til user2 select-sætningen og derefter starte bruger1-opdateringen og derefter udføre user2 select-sætningen.

---BRUGER1----BEGIN TRANSOPDATERING FrugtSalg SÆT SalgTotal =20 HVOR Id=2 VENTNING FOR FORSINKELSE '00:00:10' TILBAGETRANSAKTION ---BRUGER2----INDSTIL STATISTIK TID TIL VÆLG * FRA Frugtsalg MED (NOLOCK) WHERE Id=2

I dette trin vil vi forklare, hvordan man påvirker NOLOCK-tipset på user2 select-sætningen. Bruger1 udfører den opdaterede sætning i en eksplicit transaktion, og bruger2 udfører derefter select-sætningen, og resultatsættet returnerer uden forsinkelse transaktionsafslutningen. Dette er hovedideen i NOLOCK, den læser låste objekter.

Nu vil vi fokusere på resultatsættet af den valgte erklæring. User2 select-sætningen hentede SalesTotal-værdien 20, men den faktiske værdi af SalesTotal er stadig 8. Husk, at hvis du bruger NOLOCK-tabeltippet i din select-sætning, kan du blive udsat for denne type unøjagtige dataresultater.

Tip: "WITH" nøgleordet er en forældet funktion, så Microsoft anbefaler ikke at bruge det i din nye databaseudvikling og fjerner "WITH" nøgleordet i din nuværende udvikling. Du kan finde brugen af ​​NOLOCK-tip uden "WITH" nøgleord.

---USER1----BEGIN TRAN OPDATERING FrugtSales SÆT SalgTotal =20 WHERE Id=2 WAITFOR DELAY '00:00:10'ROLLBACK TRANSACTIONSELECT * FRA FruitSales WHERE Id=2 --USER2---SELECT * FRA FruitSales (NOLOCK) WHERE Id=2

Derudover svarer READUNCOMMITTED-tabeltippet til NOLOCK-tip, og vi kan bruge READUNCOMMITTED-tip i stedet for NOLOCK-tip.

VÆLG * FRA FruitSales (READUNCOMMITTED) HVOR Id=2

Alligevel er der en særlig sag om NOLOCK-hint, der ikke kan passere låsebarrieren. Hvis der er en proces, der ændrer en tabel, kan NOLOCK-tipset ikke overvinde denne type lås og kan ikke fortsætte læseoperationen. Årsagen til dette problem er, at NOLOCK-hintet henter Sch-S-låsen (skemastabilitet), og ALTER TABLE-sætningen henter SCH-M-låsen (skemamodifikation), så der opstår en konflikt.

Først lærer vi Object_Id of FruitSales-tabellen ved hjælp af følgende forespørgsel.

vælg OBJECT_ID('FruitSales')

Kør følgende bruger1-forespørgsel, og kør derefter bruger2-forespørgslen. Som et resultat vil bruger2-forespørgslen forsinke færdiggørelsen af ​​bruger1-tabelændringsprocessen.

--USER1---BEGIN TRANALTER TABLE FrugtSalesADD ColorofFruit varchar(200) WAITFOR DELAY '00:00:35GOCOMMIT TRAN --USER2---SELECT * FRA FruitSales (NOLOCK) WHERE Id=2

Åbn det nye forespørgselsvindue, og udfør følgende forespørgsel. Denne forespørgsel hjælper med at finde ud af låsetypen for bruger1 og bruger2 forespørgsler.

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_where_owner_id, Request_where_owner_id. 

Nu vil vi tjekke låsekompatibilitetsmatrixen for SCH-M og SCH-S interaktion. Matrixen beskriver, at SCH-M og SCH-S interaktion forårsager en konflikt.

Konklusion

I denne artikel nævnte vi den beskidte læseproces og NOLOCK-tip. Brug af NOLOCK-tip er en effektiv metode til at læse en låst side, men det har også nogle fordele og ulemper. Af denne grund skal du overveje NOLOCK-tipset, før du bruger det.

Referencer

SQL Server Transaction Locking og Row Versioning Guide

Tip (Transact-SQL) – Tabel

INSTIL TRANSAKTIONSISOLATIONSNIVEAU (Transact-SQL)


  1. Tilføj et jobtrin til et eksisterende SQL Server Agent-job (T-SQL)

  2. Sådan rettes "Serveren er ikke konfigureret til DATAADGANG" i SQL Server

  3. Sådan fungerer Date()-funktionen i SQLite

  4. Forbindelsestimeout for DriverManager getConnection