Jag är verkligen förvirrad över hur man kan smälta det faktum att en transaktion är atomär. Om en transaktion är uppsatt med ”frågor”, hur kommer det då att vara atomärt. Jag relaterar ordet ”frågor” till en allmän SQL-fråga. Därför blir en transaktion ingenting annat än en uppsättning SQL-frågor som körs samtidigt. Men det faktum att varje fråga flera operationer, jag förstår verkligen inte hur de tidigare körda frågorna (i samma uppsättning) rullar tillbaka om ett fel uppstår i en senare fråga. Vad saknar jag här? Tack!
Svar
TL; DR; Transaktionsloggen innehåller all information som är nödvändig för att återskapa eller ångra varje transaktion, beroende på om den innehåller en åtagandepost för den transaktionen eller inte.
I SQL-databaser implementeras transaktionens atomicitet oftast med loggning före skrivning (vilket innebär att transaktionsloggposterna skrivs innan de faktiska tabellerna och indexen uppdateras).
Frågor i ordets strikta mening, det vill säga SELECT
uttalanden och andra läsoperationer som inte ändrar databasens tillstånd, loggas inte eftersom det inte finns något att begå eller rulla tillbaka, och som sådan gäller inte begreppet atomicitet här, åtminstone på DBMS-nivå. Det program som förbrukar frågeresultat kan behöva genomdriva atomicitet genom att kasta resultat från tidigare frågor om någon av de efterföljande frågorna misslyckas och orsakar återställning. >, UPDATE
, DELETE
, MERGE
) och andra uttalanden som ändrar databasens tillstånd får utförs skrivs de ändringar de gör först i skriv-fram-loggen (WAL). Om alla uttalanden lyckas och ett åtagande (uttryckligt eller implicit) utfärdas, registreras detta faktum också i WAL och loggen kvarstår. Detta gör ändringarna hållbara. De kan skrivas ut till det aktuella tabell- och indexsegmentet vid något senare tillfälle, under en kontrollpunkt eller logguppspelning.
Om en av påståendena misslyckas skulle det dock inte finnas någon kommandopost i loggen för den här transaktionen, och DBMS kommer att ångra tabell- och indexändringar som hittills gjorts med de föregående loggposterna för den transaktionen.
På samma sätt, om DBMS-processen kraschar eller om strömmen släcks, kommer det inte att finnas antingen en åtagandepost för transaktionen under flygning, och de ändringar av tabellen eller index som redan har bestått kommer att ångras under återuppspelning av logg.
Kommentarer
- Detta är inte ' t korrekt: " Frågor i ordets strikta mening, det vill säga SELECT-satser och andra läsoperationer som inte ändrar databasens tillstånd, loggas inte eftersom det inte finns något att begå eller rulla tillbaka " – beroende på dina databasinställningar kan även en SELECT starta en implicit tr ansaction. brentozar.com/archive/2018/02/…
- I ' jag säger inte att de ' inte är under transaktionskontroll, jag ' säger att eftersom de är ändrar ingenting, de loggas inte.
Svar
En transaktion är atomär när den är inkapslad som detta:
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 kommer båda uppdateringarna på de två separata tabellerna att förbinda sig tillsammans, eller så kommer de att rulla tillbaka (misslyckas) tillsammans. det här är den minsta enheten i en transaktion som kommer att begås.
Men om du senare försöker köra en separat fråga utanför det omfattningen, skulle det vara en separat transaktion.
Om du försöker något så här:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837;
Och sedan gör du i din applikation andra typer av arbete, som C # -kod, och kommer sedan tillbaka till databasen senare och gör detta:
UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
Då kommer både den tidigare användaruppdateringen och din efterföljande inläggsuppdatering att lyckas, eller misslyckas, tillsammans.
Men i verkligheten kan du inte hålla en transaktion öppen som det under en längre tid eftersom du blockerar andra människor från att göra arbete i databasen. Det är därför du ofta kommer att se råd som ”Håll din transaktion kort och söt”, vilket betyder att komma in, få jobbet gjort och gå ut igen. Håll inte transaktionerna uttryckligen öppna.
Kommentarer
- En transaktion är alltid atomär, är inte ' t it?
- Ja, men beroende på dina databasinställningar kan det hända att implicita transaktioner är aktiverade – vilket betyder att du ' få en BÖRJAN TRAN även om du inte ' inte ber om det. Det varierar beroende på leverantör – till exempel hör jag Oracle som standard till implicita transaktioner, medan SQL Server inte gör det.Du TÖNKAR att du ' bara får en transaktion om du kommer från en Oracle-bakgrund, när du kanske får flera olika transaktioner i SQL Server – var och en skulle vara atomisk.