Jeg er veldig forvirret over hvordan jeg skal fordøye det faktum at en transaksjon er atomisk. Hvis en transaksjon er satt med «spørringer», hvordan vil den være atomisk. Jeg knytter ordet «spørringer» til et generelt SQL-spørsmål. Derfor blir en transaksjon ingenting annet enn et sett med SQL-spørringer utført samtidig. Men det faktum at hver spørring flere operasjoner, jeg får virkelig ikke ut hvordan de tidligere utførte spørringene (i samme sett) ruller tilbake hvis det oppstår en feil i et senere spørsmål. Hva mangler jeg her? Takk!
Svar
TL; DR; Transaksjonsloggen inneholder all informasjon som er nødvendig for å gjenopprette eller angre hver transaksjon, avhengig av om den inneholder en forpliktelsespost for den transaksjonen eller ikke.
I SQL-databaser implementeres transaksjonsatomicitet hyppigst ved bruk av forhåndslogging (som betyr at transaksjonsloggoppføringene skrives før de faktiske tabellene og indeksene oppdateres).
Spørringer i streng forstand av ordet, det vil si SELECT
utsagn og andre leseoperasjoner som ikke endrer databasetilstanden, blir ikke logget da det ikke er noe å begå eller rulle tilbake, og som sådan gjelder ikke begrepet atomicitet her, i det minste på DBMS-nivå. Programmet som bruker spørringsresultater, kan trenge å håndheve atomiciteten ved å forkaste resultatene fra tidligere spørsmål hvis en av de påfølgende spørsmålene mislykkes og forårsaker tilbakeføring.
Når DML-setninger (INSERT
, UPDATE
, DELETE
, MERGE
) og andre utsagn som endrer databasetilstanden får utført, blir endringene de gjør først skrevet inn i skriv-frem-loggen (WAL). Hvis alle uttalelser lykkes og en forpliktelse (eksplisitt eller implisitt) blir utstedt, blir dette faktum også registrert i WAL, og loggen vedvarer. Dette gjør endringene holdbare. De kan skrives ut til den faktiske tabellen og indeksesegmentene på et senere tidspunkt, under et sjekkpunkt eller loggavspilling.
Hvis en av uttalelsene mislykkes, ville det imidlertid ikke være noen kommisjonsregistrering i loggen for denne transaksjonen, og DBMS vil angre tabell- og indeksendringer som er gjort så langt ved hjelp av de foregående loggposter for den transaksjonen.
Tilsvarende, hvis DBMS-prosessen krasjer, eller strømmen går, vil det ikke være en kommisjonsregistrering for transaksjonen i flyget heller, og endringene i tabellen eller indeksen som kanskje allerede har blitt vedvarende, blir angret under omspill av logg.
Kommentarer
- Dette er ikke ' t riktig: " Spørsmål i streng forstand av ordet, det vil si SELECT-setninger og andre leseoperasjoner som ikke endrer databasetilstanden, er ikke logget da det ikke er noe å forplikte eller rulle tilbake " – avhengig av databaseinnstillingene dine, kan selv en SELECT starte en implisitt tr ansaksjon. brentozar.com/archive/2018/02/…
- I ' sier ikke at de ' ikke er under transaksjonskontroll, jeg ' sier det, siden de er ikke endrer noe, de er ikke logget.
Svar
En transaksjon er atomær når den er innkapslet som dette:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837; UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
I så fall vil begge oppdateringene på de to separate tabellene forplikte seg sammen, eller de vil rulle tilbake (mislykkes) sammen. Atomicitet betyr dette er den minste enheten i en transaksjon som skal utføres.
Hvis du senere prøver å kjøre et eget spørsmål utenfor det omfanget, vil det imidlertid være en egen transaksjon.
Hvis du prøver noe sånt som dette:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837;
Og i applikasjonen din gjør du andre typer arbeid, som C # -kode, og kommer deretter tilbake til databasen senere og gjør dette:
UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
Så vil både den tidligere brukeroppdateringen og den påfølgende innleggsoppdateringen din lykkes, eller mislykkes, sammen.
I virkeligheten kan du imidlertid ikke holde en transaksjon åpen som det over lengre tid fordi du vil blokkere andre mennesker fra å utføre arbeid i databasen. Derfor vil du ofte se råd som: «Hold transaksjonen kort og søt,» som betyr å komme inn, få jobben gjort og komme ut igjen. Ikke hold transaksjoner eksplisitt åpne.
Kommentarer
- En transaksjon er alltid atomisk, er ikke ' t it?
- Ja, men avhengig av databaseinnstillingene dine, kan det hende du har implisitte transaksjoner slått på – noe som betyr at du ' få en BEGIN TRAN selv om du ikke ' ikke ber om det. Dette varierer fra leverandør – for eksempel hører jeg Oracle er standard for implisitte transaksjoner, mens SQL Server ikke gjør det.Du TENKER at du ' bare får en transaksjon hvis du kommer fra en Oracle-bakgrunn, når du kanskje får flere forskjellige transaksjoner i SQL Server – hver av dem vil være atomiske.