Tämä artikkeli on konekäännöksen peiliartikkeli, klikkaa tästä siirtyäksesi alkuperäiseen artikkeliin.

Näkymä: 13898|Vastaus: 0

[Lähde] Lukitukset, likaiset lukemiset, toistumattomat lukemiset ja väärät lukemat SQL:ssä

[Kopioi linkki]
Julkaistu 20.7.2016 12.37.53 | | |
Yleiskatsaus sulkuihin
1. Miksi ottaa käyttöön lukot
Kun useampi käyttäjä suorittaa samanaikaisesti toimintoja tietokannassa, ilmenee seuraavia tietojen epäjohdonmukaisuuksia:
Puuttuvat päivitykset
Kaksi käyttäjää, A ja B, lukevat saman datan ja muokkaavat sitä, ja toisen käyttäjän muutoksen tulos tuhoaa toisen muutoksen, kuten lippujen varausjärjestelmän, tuloksen
Likainen lukeminen
Käyttäjä A muokkaa dataa, ja käyttäjä B lukee tiedot, mutta käyttäjä A peruuttaa muokkauksen jostain syystä, jolloin data palautuu alkuperäiseen arvoonsa
Älä lue toistuvasti
Käyttäjä A lukee tiedot, ja käyttäjä B lukee tiedot ja muokkaa sitä
Pääasiallinen samanaikaisuuden hallinnan menetelmä on blokkaus, eli kieltää käyttäjiä tekemästä tiettyjä toimintoja tietyn ajan tietojen epäjohdonmukaisuuksien välttämiseksi

2. Lukkojen luokittelu
Sulkuja jaetaan kahteen kategoriaan:
1 . Tietokantajärjestelmän näkökulmasta: se on jaettu eksklusiivisiin lukkoihin (eli yksinoikeudellisiin lukkoihin), jaettuihin lukkoihin ja päivityslukkoihin
MS - SQL Server käyttää seuraavia resurssilukitusmalleja.
Lukitustilan kuvaus
Share(t) käytetään operaatioihin, jotka eivät muuta tai päivitä dataa (vain luku -toiminnot), kuten SELECT-lauseet.
Päivitys (U) on käytössä päivitettävissä resursseissa. Estää yleiset kuolleiden tilanteet, kun useita istuntoja luetaan, lukitaan ja mahdollisesti tapahtuu resurssipäivitys.
Eksklusiivinen (X) käytetään datan muokkausoperaatioissa, kuten INSERT, UPDATE tai DELETE. Varmista, ettei useita päivityksiä tehdä samalla resurssilla samanaikaisesti.
Intent Locks -lukkoja käytetään lukkojen hierarkian luomiseen. Intent lock -tyypit ovat: Intent Shared (IS), Intent Exclusive (IX) ja Intent Exclusive (SIX).
Skeemalukkoja käytetään operaatioissa, jotka riippuvat taulukon skeemasta. Skeemalukkojen tyypit ovat: skeeman muokkaus (Sch -M) ja skeeman stabiilisuus (Sch -S).
Massapäivityksiä (BU) käytetään, kun suuria määriä dataa kopioidaan taulukkoon ja TABLOCK-vihje määritellään.
Jaetut lukot
Jaettu lukko mahdollistaa samanaikaisten tapahtumien lukemisen (SELECT) resurssin. Kun resurssissa on jaettu (S)-lukko, mikään muu transaktio ei voi muuttaa dataa. Vapauta jaettu (S)-lukko resurssissa heti, kun data on luettu, ellei transaktioiden eristystaso ole asetettu toistettavaksi tai korkeammaksi, tai jaettu (S)-lukko säilytetään lukitusvihjeellä koko transaktion elinkaaren ajan.
Päivityslukko
Päivitys (U) -lukot estävät pattitilanteet normaalissa muodossaan. Tyypillinen päivitysmalli koostuu transaktiosta, joka lukee tietueen, saa jaetun (S)-lukon resurssille (sivu tai rivi) ja muokkaa sitten riviä, jolloin lukko on muunnettava eksklusiiviseksi (X)-lukoksi. Jos kaksi transaktiota saa jaetun tilan lukon resurssiin ja yrittää päivittää tietoja samanaikaisesti, toinen tapahtuma yrittää muuntaa lukon eksklusiiviseksi (X) lukoksi. Siirtyminen jaetusta tilasta yksinoikeudelleen lukitukseen joutuu odottamaan hetken, koska yhden transaktion yksinoikeudellinen lukitus ei ole yhteensopiva toisen transaktion jaetun tilan lukon kanssa; Tapahtuu lukitusodotus. Toinen tapahtuma pyrkii saamaan yksinoikeudella (X) lukon päivitystä varten. Pattitilanne syntyy, koska molemmat tapahtumat muunnetaan yksinoikeudetuiksi (X)-lukkoiksi, ja jokainen tapahtuma odottaa, että toinen transaktio vapauttaa jaetun tilan lukon.
Välttääksesi tämän mahdollisen deadlock-ongelman, käytä päivitettyä (U) lukkoa. Vain yksi tapahtuma kerrallaan voi saada päivitetyn (U) lukituksen resurssille. Jos transaktio muuttaa resurssia, päivitys (U) -lukko muutetaan eksklusiiviseksi (X)-lukoksi. Muussa tapauksessa lukko muutetaan jaetuksi lukoksi.
Eksklusiiviset lukot
Eksklusiiviset (X) lukot estävät samanaikaisten tapahtumien pääsyn resursseihin. Muut tapahtumat eivät voi lukea tai muokata yksinoikeudella (X)-lukolla lukittua dataa.
Intent-lukko
Intent-lukko tarkoittaa, että SQL Serverin tulee hankkia jaettu (S)-lukko tai yksinoikeudella (X) lukko joihinkin hierarkian taustalla oleviin resursseihin. Esimerkiksi taulutasolla oleva share-intent-lukko tarkoittaa, että transaktio aikoo asettaa share(S)-lukon taulun sivulle tai riville. Intent-lukon asettaminen taulutasolla estää toista transaktiota saamasta myöhemmin eksklusiivista (X)-lukkoa taululle, joka sisältää kyseisen sivun. Intent-lukot voivat parantaa suorituskykyä, koska SQL Server tarkistaa intent-lukon vain taulutasolla selvittääkseen, voiko transaktio turvallisesti saada lukon kyseiselle pöydälle. Sen sijaan, että tarkistaisit jokaisen rivin tai sivun lukot taulukossa, voiko transaktio lukita koko taulukon.
Intent-lukkoihin kuuluvat Intent Sharing (IS), Intent Exclusive (IX) ja Intent Exclusive Sharing (SIX).
Lukitustilan kuvaus
Intent Sharing (IS) osoittaa, että transaktion tarkoitus on osa, ei kaikki, lukuhierarkian taustalla olevista resursseista, asettamalla S-lukot jokaiselle resurssille.
Intent Exclusive (IX) tarkoittaa, että transaktion tarkoituksena on muuttaa joitakin, mutta ei kaikkia, hierarkian taustalla olevia resursseja asettamalla X-lukko jokaiselle resurssille. IX on IS:n yläjoukko.
Eksklusiivinen jakaminen tarkoituksella (SIX) tarkoittaa, että transaktion tarkoitus on lukea kaikki hierarkian taustalla olevat resurssit ja muokata joitakin, mutta ei kaikkia, niistä asettamalla IX-lukkoja jokaiselle resurssille. Salli samanaikaiset IS-lukitukset ylimmän tason resursseissa. Esimerkiksi taulukon SIX-lukko asettaa SIX-lukon pöydälle (mahdollistaen samanaikaiset IS-lukit) ja IX-lukon tällä hetkellä muokatulle sivulle (X-lukko muokatulle riville). Vaikka jokaisella resurssilla voi olla vain yksi SIX-lukko tietyn ajan, jotta muut transaktiot eivät päivittäisi resurssia, muut transaktiot voivat lukea hierarkian taustalla olevia resursseja hankkimalla taulukkotason IS-lukkoja.
Yksinoikeudellinen lukko: Vain ohjelma, joka suorittaa lukitustoiminnon, saa käyttää sitä, eikä muita sen operaatioita hyväksytä. Kun suoritat tietojen päivityskomennon, SQL Server käyttää automaattisesti yksinoikeudella lukitusta. Kun esineessä on muita lukkoja, siihen ei voi lisätä eksklusiivista lukkoa.
Jaettu lukko: Jaetun lukon lukitsema resurssi voidaan lukea muiden käyttäjien toimesta, mutta muut käyttäjät eivät voi muokata sitä.
Päivityslukko: Kun SQL Server on valmis päivittämään dataa, se lukitsee ensin datakohteen, jotta dataa ei voi muokata mutta ne voidaan lukea. Kun SQL Server päättää haluavansa päivittää tietoja, se korvaa päivityslukon automaattisesti eksklusiivisella lukolla, eikä voi lisätä päivityslukkoa, kun objektissa on muita lukkoja.

2 . Ohjelmoijan näkökulmasta: se jaetaan optimistiseen lukkoon ja pessimistiseen lukkoon.
Optimism Lock: Luottaa täysin tietokantaan lukon työn hallinnassa.
Pessimistiset lukot: Ohjelmoijat hallitsevat itse datan tai objektien lukkokäsittelyä.
MS - SQLSERVER käyttää lukkoja toteuttaakseen pessimististä samanaikaisuuden hallintaa useiden käyttäjien välillä, jotka suorittavat samanaikaisesti muokkauksia tietokantaan

3. Lukon hiukkaskoko
Lukon rakeisuus on estetyn kohteen koko, pieni blokkausrakeisuus on korkea samanaikaisuus, mutta ylikuorma on suuri, ja suuri blokkausgranulaarisuus on pieni samanaikaisuus, mutta ylikuorma on pieni
SQL Server tukee lukitustarkkuutta riveille, sivuille, avaimille, avainalueille, indekseille, taulukoille tai tietokannoille
Resurssikuvaus
RID-rivin tunniste. Käytetään lukitsemaan rivi pöytään yksitellen.
Avainrivilukitus indeksiin. Käytetään suojaamaan avainaluetta sarjallistettavissa tapahtumissa.
8 kilotavua (KB) tietosivuja tai hakemistosivuja.
Laajennettu levy Kahdeksan vierekkäisen tietosivun tai indeksisivun joukko.
Taulukko Koko taulukko sisältäen kaikki tiedot ja indeksit.
Tietokanta.
4. Lukitusajan pituus
Lukon pidettävyyden pituus on aika, joka tarvitaan resurssin suojaamiseen pyydetyllä tasolla.
Jaetun lukon pitoaika, jota käytetään lukutoimintojen suojaamiseen, riippuu transaktioiden eristystasosta. Kun oletustransaktioiden eristystaso on READ COMMITTED, jaettua lukkoa ohjataan vain lukusivun ajan. Skannauksessa lukkoa ei vapauteta ennen kuin lukko on löydetty seuraavalta sivulta skannauksessa. Jos määrität HOLDLOCK-kehotteen tai asetat transaktioiden eristystason REPEATABLE READ tai SERIALIZABLE, lukkoa ei vapauteta ennen kuin transaktio päättyy.
Kursorin samanaikaisuusasetuksen mukaan kursori voi saada scroll-lukon jaetussa tilassa suojatakseen uutin. Kun rullauslukko on tarpeen, rullauslukko vapautetaan vasta seuraavalla kerralla, kun kursori poistetaan tai suljetaan – kumpi tapahtuu ensin. Jos kuitenkin määrität HOLDLOCKin, rullauslukko vapautetaan vasta tapahtuman lopussa.
Päivityksen suojaamiseen käytetty yksinoikeudellinen lukko ei vapauteta ennen tapahtuman päättymistä.
Jos yhteys yrittää saada lukon, joka on ristiriidassa toisen yhteyden hallitseman lukon kanssa, lukon hankkimista yrittävä yhteys estetään kunnes:
Ristiriitainen lukko vapautetaan ja yhteys saa pyydetyn lukon.
Yhteyden aikakatkaisu on umpeutunut. Oletuksena aikakatkaisuväliä ei ole, mutta jotkut sovellukset asettavat aikakatkaisuvälit estääkseen rajattoman odotuksen

Viisi lukkojen räätälöintiä SQL Serverissä
1 Käsittele kuolleita lukkoja ja aseta kuolleiden lukkojen prioriteetit
Pattitilanne tarkoittaa loputonta odotusta, jonka aiheuttaa useiden käyttäjien hakeminen eri lohkoihin, koska hakijalla on osa eston oikeutta ja odottaa osittaista estettä muiden käyttäjien omistamia
Voit käyttää SET-DEADLOCK_PRIORITY hallitaksesi session reaktiota pattitilanteen sattuessa. Jos molemmat prosessit lukitsevat datan, eikä kumpikaan voi vapauttaa omaa lukkoaan ennen kuin toinen prosessi vapauttaa oman lukonsa, syntyy umpikujatilanne.

2 Käsittele aikakatkaisut ja aseta lukituksen aikakatkaisuajat.
@@LOCK_TIMEOUT Palauttaa nykyisen lukituksen aikakatkaisuasetuksen nykyiselle istunnolle millisekunteina
SET LOCK_TIMEOUT -asetus mahdollistaa sovelluksen asettaa maksimiajan, jonka lause odottaa resurssin estämiseksi. Kun lauseen odotusaika on suurempi kuin LOCK_TIMEOUT-asetus, järjestelmä peruuttaa estolauseen automaattisesti ja palauttaa sovellukselle virheilmoituksen 1222, että lukituspyynnön aikakatkaisuaika on ylittynyt

esimerkki
Seuraavassa esimerkissä lukituksen aikakatkaisuaika on asetettu 1 800 millisekuntiin.
ASETA LOCK_TIMEOUT1800

3) Aseta transaktioiden eristystaso.

4) Käytä taulukkotason lukitusvihjeitä SELECT-, INSERT-, UPDATE- ja DELETE-lausemuksille.

5) Määritä indeksin lukitusrakeisuus
Voit käyttää sp_indexoption järjestelmään tallennettuja proseduureja lukon tarkkuuden asettamiseen indeksointia varten

6. Katso lukon tiedot

1 Suorita EXEC SP_LOCK raportoi tietoa lukosta
2 Paina Ctrl + 2 kyselyanalysaattorissa nähdäksesi lukon tiedot

7. Varotoimet käytössä

Kuinka välttää pattitilanteet
1. Kun käytät transaktioita, yritä lyhentää transaktioiden loogista käsittelyä ja lähetä tai peruuta tapahtumat ajoissa.
2 Aseta deadlock-aikakatkaisuparametri kohtuulliselle alueelle, kuten: 3 minuuttia - 10 minuuttia; Ajan myötä operaatio keskeytetään automaattisesti, jotta prosessi ei jumittuisi;
3. Optimoi ohjelma, tarkista ja vältä pattitilanteen ilmiötä;
4. Testaa kaikki skriptit ja pelit huolellisesti ennen tarkkaa versiota.
5 Kaikissa peleissä täytyy olla virheenkäsittely (@error kautta)
6 Älä muokkaa SQL SERVER -transaktioiden oletustasoa. Pakotettu lukitus ei ole suositeltavaa

Ratkaise ongelma Kuinka lukita rivitaulutietokanta

8. Useita kysymyksiä lukoista

1 Kuinka lukita pöytärivi
ASETA TRANSAKTIONERISTÄMISEN TASO READUNCOMCOMMITED.
VALITSE *taulukosta ROWLOCK, missä id = 1

2 Lukitse taulukko tietokantaan
VALITSE *TAULUKOSTA WITH( HOLDLOCK )

Lukituslausunto:
sybase:
Päivitä taulukkosetti col1 = col1, missä 1= 0 ;
MSSQL:
valitse col1 taulukosta (tablockx), missä 1= 0 ;
oracle:
LUKITSEE TAULUKKO EKSKLUSIIVISESSA TILASSA ;
Kun lukko on lukittu, kukaan muu ei voi käyttää sitä ennen kuin lukittu käyttäjä avaa sen, ja lukko avataan commit- tai rollback-toiminnolla

Muutama esimerkki auttaa syventämään vaikutelmaasi
Aseta taulukko1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3

1) Eksklusiivinen lukko
Luo kaksi uutta yhteyttä
Suorita seuraava lause ensimmäisessä yhteydessä
aloita tran
Päivitystaulukko 1
joukko A= ' aa '
missä B= ' b2 '
odota viivettä' 00:00:30' --odota 30 sekuntia
commit tran
Suorita seuraava lause toisessa yhteydessä
aloita tran
valitse *taulukosta 1
missä B= ' b2 '
commit tran

Jos edellä mainitut kaksi lausetta suoritetaan samanaikaisesti, select-kyselyn täytyy odottaa päivityksen suorittamista, eli odottaa 30 sekuntia

2) Yhteinen lukko
Suorita seuraava lause ensimmäisessä yhteydessä
aloita tran
valitse *taulukosta 1 pidätyslukko – pidätyslukko lisätään keinotekoisesti lukkoon
missä B= ' b2 '
odota viivettä' 00:00:30' --odota 30 sekuntia
commit tran

Suorita seuraava lause toisessa yhteydessä
aloita tran
valitse A,C taulukosta 1
missä B= ' b2 '
Päivitystaulukko 1
joukko A= ' aa '
missä B= ' b2 '
commit tran

Jos yllä mainitut kaksi lausetta suoritetaan samanaikaisesti, valintakysely toisessa yhteydessä voidaan suorittaa
Päivityksen täytyy odottaa ensimmäistä tapahtumaa, joka vapauttaa jaetun lukon, ja muuntaa se yksinoikeudella lukoksi ennen kuin se voidaan suorittaa, eli odottaa 30 sekuntia

3) Pattitilanne
Lisätty taulukko2(D,E)
D E
d1 e1
d2 e2
Suorita seuraava lause ensimmäisessä yhteydessä
aloita tran
Päivitystaulukko 1
joukko A= ' aa '
missä B= ' b2 '
odota viivettä' 00:00:30'
Päivitystaulukko 2
joukko D= ' d5 '
missä E= ' e1 '
commit tran

Suorita seuraava lause toisessa yhteydessä
aloita tran
Päivitystaulukko 2
joukko D= ' d5 '
missä E= ' e1 '
odota viivettä' 00:00:10'
Päivitystaulukko 1
joukko A= ' aa '
missä B= ' b2 '
commit tran

Samaan aikaan järjestelmä havaitsee pattitilanteen ja keskeyttää prosessin

Lisäyksenä:
SQL Server 2000:n tukemat taulukkotason lukitusvihjeet

HOLDLOCK pitää jaettua lukkoa hallussaan, kunnes koko transaktio on valmis, ja se tulisi vapauttaa heti, kun lukittua objektia ei tarvita, mikä vastaa SERIALIZET-transaktioiden eristystasoa
NOLOCK-lauseke suoritetaan ilman jaettua lukkoa, jolloin sallitaan likaiset lukemiset, mikä vastaa READ UNCOMMITTED -transaktioiden eristystasoa
PAGLOCK käyttää useita sivulukkoja, joissa käytetään yhtä taulukkolukkoa
READPASTin avulla sql-palvelin voi ohittaa lukitut rivit ja suorittaa transaktioita, ja READ UNCOMMITTED -eristystasoilla ohittaa vain RID-lukot, ei sivu-, vyöhyke- ja taulukolukkoja
ROWLOCK valvoo rivilukkojen käyttöä
TABLOCKX vaatii yksinoikeudella taulukkotason lukituksen käyttöä, mikä estää muita transaktioita käyttämästä taulukkoa transaktion aikana
UPLOCK pakottaa päivityksiä käyttämään taulukkoa, jossa ei ole jaettua lukkoa

App Lock:
Sovelluslukko on lukko, jonka luo asiakaskoodi, ei SQL Serverin itsensä luoma lukko

Kaksi prosessia sovelluslukkojen käsittelyyn
sp_getapplock Lukitse sovellusresurssit
sp_releaseapplock Avaa sovellusresurssit

Huomautus: Ero taulun lukitsemisessa tietokantaan

VALITSE *TAULUKOSTA WITH( HOLDLOCK ) Muut transaktiot voivat lukea taulua, mutta eivät voi päivittää tai poistaa
VALITSE *FROM table WITH(TABLOCKX) Muut transaktiot eivät voi lukea, päivittää tai poistaa taulukkoa





Edellinen:Ei ollut mitään päätekuuntelua http://localhost:111/xxx.svc se c...
Seuraava:SQL lukitsee NOLOCK, HOLDLOCK, UPDLOCK, TABLOCK, TABLOCKX
Vastuuvapauslauseke:
Kaikki Code Farmer Networkin julkaisemat ohjelmistot, ohjelmamateriaalit tai artikkelit ovat tarkoitettu vain oppimis- ja tutkimustarkoituksiin; Yllä mainittua sisältöä ei saa käyttää kaupallisiin tai laittomiin tarkoituksiin, muuten käyttäjät joutuvat kantamaan kaikki seuraukset. Tämän sivuston tiedot ovat peräisin internetistä, eikä tekijänoikeuskiistat liity tähän sivustoon. Sinun tulee poistaa yllä oleva sisältö kokonaan tietokoneeltasi 24 tunnin kuluessa lataamisesta. Jos pidät ohjelmasta, tue aitoa ohjelmistoa, osta rekisteröityminen ja hanki parempia aitoja palveluita. Jos rikkomuksia ilmenee, ota meihin yhteyttä sähköpostitse.

Mail To:help@itsvse.com