Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 13898|Svar: 0

[Källa] Lås, smutsiga läsningar, oupprepbara läsningar och falska läsningar i SQL

[Kopiera länk]
Publicerad på 2016-07-20 12:37:53 | | |
Översikt över slussar
1. Varför införa lås
När flera användare utför samtidiga operationer på databasen samtidigt uppstår följande datainkonsistenser:
Saknade uppdateringar
Två användare, A och B, läser samma data och ändrar den, och resultatet av en användares modifiering förstör resultatet av den andra modifieringen, såsom biljettbokningssystemet
Smutsig läsning
Användare A ändrar datan, och sedan läser användare B upp datan, men användare A avbryter av någon anledning ändringen av datan, och datan återgår till sitt ursprungliga värde
Läs inte om och om igen
Användare A läser datan, och sedan läser användare B datan och ändrar den
Den huvudsakliga metoden för samtidighetskontroll är blockering, vilket innebär att användare förbjuder att utföra vissa operationer under en viss tid för att undvika datainkonsekvenser

2. Klassificering av slussar
Det finns två indelningar i kategorier av slussar:
1 . Ur databassystemets perspektiv: det är uppdelat i exklusiva lås (dvs. exklusiva lås), delade lås och uppdateringslusar
MS - SQL Server använder följande resurslåsmönster.
Låslägesbeskrivning
Share(s) används för operationer som inte ändrar eller uppdaterar data (skrivskyddade operationer), såsom SELECT-satser.
Update (U) används i uppdaterbara resurser. Förhindrar vanliga former av deadlocks när flera sessioner läses, låss och eventuellt en resursuppdatering som kan ske.
Exklusiv (X) används för datamodifieringsoperationer, såsom INSERT, UPDATE eller DELETE. Se till att flera uppdateringar inte utförs på samma resurs samtidigt.
Avsiktslås används för att etablera en hierarki av lås. Typerna av avsiktslås är: Avsiktsdelad (IS), Avsiktsexklusiv (IX) och Avsiktsexklusiv (SEX).
Schemalås används vid utförande operationer som är beroende av tabellschemat. Typerna av schemalås är: schemamodifiering (Sch -M) och schemastabilitet (Sch -S).
Bulkuppdateringar (BU) används när stora datamängder kopieras till en tabell och en TABLOCK-hint anges.
Delade slussar
Ett delat lås tillåter samtidiga transaktioner att läsa (SELECTA) en resurs. När ett delat (S)-lås finns på en resurs kan ingen annan transaktion ändra datan. Släpp det delade (S)-låset på resursen så snart datan har lästs, om inte transaktionsisoleringsnivån är inställd till upprepbar eller högre, eller om det delade (S)-låset behålls med en lås-hint under hela transaktionens livstid.
Uppdateringslås
Uppdateringslås (U) förhindrar deadlocks i sin vanliga form. Ett typiskt uppdateringsmönster består av en transaktion som läser en post, får ett delat (S)-lås för en resurs (sida eller rad), och sedan modifierar en rad, vilket kräver att låset konverteras till ett exklusivt (X)-lås. Om två transaktioner får ett delat lägeslås på en resurs och sedan försöker uppdatera datan samtidigt, försöker en transaktion konvertera låset till ett exklusivt (X) lås. Övergången från delat läge till exklusivt lås måste vänta ett tag eftersom det exklusiva låset för en transaktion inte är kompatibelt med det delade lägeslåset för en annan transaktion; En låsväntan inträffar. Den andra transaktionen försöker få ett exklusivt (X) lås för en uppdatering. En deadlock uppstår eftersom båda transaktionerna omvandlas till exklusiva (X) lås, och varje transaktion väntar på att den andra transaktionen ska släppa det delade lägeslåset.
För att undvika detta potentiella deadlock-problem, använd ett uppdaterat (U)-lås. Endast en transaktion åt gången kan få ett uppdaterat (U)-lås för en resurs. Om transaktionen modifierar resursen omvandlas uppdateringslåset (U) till ett exklusivt (X) lås. Annars omvandlas låset till ett delat lås.
Exklusiva lås
Exklusiva (X) lås förhindrar samtidiga transaktioner från att få tillgång till resurser. Andra transaktioner kan inte läsa eller ändra data som är låst av det exklusiva (X)-låset.
Intentionslås
Ett avsiktslås indikerar att SQL Server behöver skaffa ett delat (S) lås eller ett exklusivt (X) lås på några av de underliggande resurserna i hierarkin. Till exempel indikerar ett share-intent-lås placerat på tabellnivå att transaktionen avser att placera ett share(s)-lås på en sida eller rad i tabellen. Att sätta ett intentionslås på tabellnivå förhindrar att en annan transaktion senare får ett exklusivt (X) lås på tabellen som innehåller den sidan. Intent locks kan förbättra prestandan eftersom SQL Server endast kontrollerar intent lock på tabellnivå för att avgöra om en transaktion säkert kan få ett lock på den tabellen. Istället för att kontrollera låsen på varje rad eller sida i tabellen för att avgöra om en transaktion kan låsa hela tabellen.
Avsiktslås inkluderar Intent Sharing (IS), Intent Exclusive (IX) och Intent Exclusive Sharing (SIX).
Låslägesbeskrivning
Intent Sharing (IS) indikerar att transaktionens avsikt är några, inte alla, av de underliggande resurserna i läshierarkin genom att placera S-lås på varje resurs.
Avsiktsexklusiv (IX) indikerar att transaktionens avsikt är att modifiera vissa, men inte alla, av de underliggande resurserna i hierarkin genom att placera ett X-lås på varje resurs. IX är en övermängd av IS.
Exklusiv delning med avsikt (SIX) indikerar att transaktionens avsikt är att läsa alla underliggande resurser i hierarkin och modifiera några, men inte alla, av de underliggande resurserna genom att placera IX-lås på varje resurs. Tillåt samtidiga IS-lås på toppnivåresurser. Till exempel placerar en tabells SIX-lås ett SIX-lås på tabellen (vilket tillåter samtidiga IS-lås) och ett IX-lås på den för närvarande modifierade sidan (ett X-lås på den modifierade raden). Medan varje resurs bara kan ha ett SIX-lås under en period för att förhindra att andra transaktioner uppdaterar resursen, kan andra transaktioner läsa de underliggande resurserna i hierarkin genom att skaffa tabellnivå-IS-lås.
Exklusivt lås: Endast programmet som utför låsoperationen får använda det, och andra operationer på det accepteras inte. När du kör ett datauppdateringskommando använder SQL Server automatiskt ett exklusivt lås. När andra lås finns på ett objekt kan du inte lägga till ett exklusivt lås på det.
Delat lås: Resursen som är låst av det delade låset kan läsas av andra användare, men andra användare kan inte ändra den.
Uppdateringslås: När SQL Server är redo att uppdatera data låser den först dataobjektet så att datan inte kan ändras utan kan läsas. När SQL Server fastställer att den vill uppdatera data kommer den automatiskt att ersätta uppdateringslåset med ett exklusivt lås, och kan inte lägga till ett uppdateringslås när andra lås finns på objektet.

2 . Ur programmerarens synvinkel: det är uppdelat i optimistisk låsning och pessimistisk låsning.
Optimism Lock: Är helt beroende av databasen för att hantera låsets arbete.
Pessimistiska lås: Programmerare hanterar låshantering på data eller objekt i sig.
MS - SQLSERVER använder lås för att implementera pessimistisk samtidighetskontroll mellan flera användare som samtidigt utför ändringar i databasen

3. Partikelstorleken på låset
Låsgranulariteten är storleken på det blockerade målet, den lilla blockeringsgranulariteten är hög samtidighet, men overheaden är stor, och den stora blockeringsgranulariteten är låg samtidighet men overheaden är liten
SQL Server stödjer låsgranularitet för rader, sidor, nycklar, nyckelintervall, index, tabeller eller databaser
Resursbeskrivning
RID-radidentifierare. Brukade låsa en rad i ett bord individuellt.
Nyckelradslås i indexet. Används för att skydda nycklarna i serialiserbara transaktioner.
8 kilobyte (KB) datasidor eller indexsidor.
Utökad disk En uppsättning av åtta intilliggande datasidor eller indexsidor.
Tabell Hela tabellen inklusive all data och index.
DB-databas.
4. Tiden för låsningen
Den tid ett lås hålls är den tid som krävs för att skydda resursen på den begärda nivån.
Hålltiden för det delade låset som används för att skydda läsoperationer beror på transaktionsisoleringsnivån. Med standardnivån för transaktionsisolering READ COMMITTED kontrolleras det delade låset endast under lässidans varaktighet. Vid en skanning släpps inte låset förrän låset är på nästa sida inom skanningen. Om du anger en HOLDLOCK-prompt eller sätter transaktionsisoleringsnivån till REPEATABLE READ eller SERIALIZABLE, släpps inte låset förrän transaktionen avslutas.
Beroende på samtidighetsalternativet som är inställt för markören kan markören få ett scrolllås i delat läge för att skydda extraktet. När ett scrolllås krävs släpps scrolllåset inte förrän nästa gång markören extraheras eller stängs, beroende på vad som inträffar först. Men om du anger en HOLDLOCK släpps scroll-låset inte förrän i slutet av transaktionen.
Det exklusiva låset som används för att skydda uppdateringen kommer inte att släppas förrän i slutet av transaktionen.
Om en anslutning försöker få ett lås som krockar med ett lås som kontrolleras av en annan anslutning, kommer anslutningen som försöker få låset att blockeras tills:
Det motstridiga låset släpps och anslutningen får det begärda låset.
Anslutningstimeouten har gått ut. Det finns inget timeout-intervall som standard, men vissa appar sätter timeout-intervaller för att förhindra oändlig väntan

Fem anpassningar av lås i SQL Server
1 Hantera deadlocks och sätta deadlock-prioriteringar
Deadlock är den oändliga väntan som orsakas av flera användare som ansöker om olika blockeringar, eftersom sökanden har en del av blockeringsrätten och väntar på den delvisa blockeringen som ägs av andra användare
Du kan använda SET-DEADLOCK_PRIORITY för att styra hur sessionen reagerar vid ett deadlock-tillstånd. Om båda processerna låser datan, och varje process inte kan släppa sitt eget lås förrän den andra processen släpper sitt eget lås, uppstår en deadlock-situation.

2 Hantera timeouts och ställ in timeout-tider för lås.
@@LOCK_TIMEOUT Returnerar den aktuella låstidsinställningen för den aktuella sessionen i millisekunder
SET LOCK_TIMEOUT-inställningen tillåter applikationen att ställa in den maximala tiden som satsen väntar för att blockera resursen. När väntetiden för satsen är längre än LOCK_TIMEOUT-inställningen avbryter systemet automatiskt blockeringssatsen och skickar till applikationen ett felmeddelande 1222 om att tidsavslutningsperioden för låsförfrågningar har överskridits

exempel
I följande exempel är låstidsperioden satt till 1 800 millisekunder.
STÄLL LOCK_TIMEOUT1800

3) Sätt transaktionsisoleringsnivån.

4) Använd låstips på tabellnivå för SELECT, INSERT, UPDATE och DELETE-satser.

5) Konfigurera låsgranulariteten för indexet
Du kan använda sp_indexoption systemlagrade procedurer för att ställa in låsgranulariteten för indexering

6. Se informationen om slussen

1 Utför EXEC SP_LOCK rapportera information om låset
2 Tryck Ctrl + 2 i frågeanalysatorn för att se informationen om låset

7. Försiktighetsåtgärder för användning

Hur man undviker dödläge
1. När du använder transaktioner, försök att förkorta den logiska bearbetningsprocessen för transaktioner och skicka in eller rulla tillbaka transaktioner tidigt.
2 Sätt deadlock-timeout-parametern till ett rimligt intervall, såsom: 3 minuter - 10 minuter; Efter tiden avbryts operationen automatiskt för att undvika att processen hänger;
3. Optimera programmet, kontrollera och undvika deadlock-fenomenet;
4. Testa alla skript och SP:er noggrant innan exakt version.
5 Alla SP måste ha felhantering (via @error)
6 Ändra inte standardnivån för SQL SERVER-transaktioner. Tvångslåsning rekommenderas inte

Lös problemet: Hur låser man en radtabellsdatabas

8. Flera frågor om lås

1 Hur man låser en rad i ett bord
SET TRANSACTIONISOLATION LEVEL READUNCOMMITTED
VÄLJ *FRÅN tabellen ROWLOCKWHERE id = 1

2 Lås en tabell i databasen
VÄLJ *FRÅN tabell MED( HOLDLOCK )

Lock-uttalande:
sybase:
uppdatera tabelluppsättningen kol1 = kol1 där 1= 0 ;
MSSQL:
Välj kol1från tabell (tablockx) där 1= 0 ;
oracle:
LÅSBORDSTABELL I EXKLUSIVT LÄGE ;
Efter att låset är låst kan ingen annan använda det förrän den låsta användaren låser upp det, och det låses upp med commit eller rollback

Några exempel hjälper dig att fördjupa ditt intryck
Settabell1(A,B,C)
A B C
A1 B1 C1
A2 B2 C2
A3 B3 C3

1) Exklusivt lås
Skapa två nya kopplingar
Exekver följande sats i den första anslutningen
Begin Tran
Uppdateringstabell1
set A= ' aa '
där B= ' b2 '
vänta på fördröjning' 00:00:30' --vänta 30 sekunder
commit tran
Exekver följande sats i den andra anslutningen
Begin Tran
Välj *från tabell1
där B= ' b2 '
commit tran

Om de två ovanstående satserna körs samtidigt måste select-frågan vänta på att uppdateringen ska köras, det vill säga vänta 30 sekunder

2) Delat lås
Exekver följande sats i den första anslutningen
Begin Tran
välj *från tabell1 holdlock - holdlocken läggs konstgjort till låset
där B= ' b2 '
vänta på fördröjning' 00:00:30' --vänta 30 sekunder
commit tran

Exekver följande sats i den andra anslutningen
Begin Tran
välj A,C från tabell1
där B= ' b2 '
Uppdateringstabell1
set A= ' aa '
där B= ' b2 '
commit tran

Om de två ovanstående satserna körs samtidigt kan select-frågan i den andra anslutningen köras
Uppdateringen måste vänta på den första transaktionen för att släppa det delade låset och konvertera det till ett exklusivt lås innan det kan köras, det vill säga vänta 30 sekunder

3) Dödläge
Tillagd tabell2(D,E)
D E
d1 e1
d2 e2
Exekver följande sats i den första anslutningen
Begin Tran
Uppdateringstabell1
set A= ' aa '
där B= ' b2 '
vänta på fördröjning' 00:00:30'
Uppdateringstabell2
mängden D= ' d5 '
där E= ' e1 '
commit tran

Exekver följande sats i den andra anslutningen
Begin Tran
Uppdateringstabell2
mängden D= ' d5 '
där E= ' e1 '
vänta på försening' 00:00:10'
Uppdateringstabell1
set A= ' aa '
där B= ' b2 '
commit tran

Samtidigt upptäcker systemet deadlocken och avbryter processen

För att tillägga:
Tabellnivå-låstips som stöds av SQL Server 2000

HOLDLOCK håller det delade låset tills hela transaktionen är slutförd och bör släppas så snart det låsta objektet inte längre behövs, motsvarande nivån för SERIALIZABLE transaktionsisolering
NOLOCK-satsen exekveras utan att utfärda ett delat lås, vilket tillåter dirty reads, vilket motsvarar nivån för READ UNCOMMITTED transaktionsisolering
PAGLOCK använder flera sidlås där ett tabelllås används
READPAST låter SQL-servern hoppa över låsta rader och utföra transaktioner, och för READ UNCOMMITTED transaktionsisoleringsnivåer hoppar man bara över RID-lås, inte sid-, zon- och tabelllås
ROWLOCK upprätthåller användningen av rowlocks
TABLOCKX upprätthåller användningen av ett exklusivt tabellnivålås, vilket förhindrar att andra transaktioner använder tabellen under transaktionen
UPLOCK tvingar användning av uppdateringar när man läser en tabell utan delat lås

Applås:
Ett applikationslås är ett lås som genereras av klientkod, inte ett lås som genereras av SQL Server själv

Två processer för hantering av applikationslås
sp_getapplock Låsa applikationsresurser
sp_releaseapplock Lås upp applikationsresurserna

Obs: Skillnaden mellan att låsa en tabell i en databas

VÄLJ *FRÅN tabell MED( HOLDLOCK ) Andra transaktioner kan läsa tabellen, men kan inte uppdatera och ta bort
VÄLJ *FRÅN tabellen WITH(TABLOCKX) Andra transaktioner kan inte läsa, uppdatera och ta bort tabellen





Föregående:Det fanns inget slutpunkt som lyssnade på http://localhost:111/xxx.svc den där k...
Nästa:SQL-lås NOLOCK, HOLDLOCK, UPDLOCK, TABLOCK, TABLOCKX
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com