Ik weet echt niet hoe ik het feit dat een transactie atomair is, moet verwerken. Als een transactie een reeks “queries” is, hoe zal deze dan atomair zijn. Ik breng het woord “queries” in verband met een algemene SQL-query. Daarom wordt een transactie dan niets anders dan een set SQL-queries die tegelijkertijd worden uitgevoerd. Maar het feit dat elke query meerdere bewerkingen heeft, begrijp ik echt niet hoe de eerder uitgevoerde querys (in dezelfde set) terugdraaien als er een fout optreedt in een latere query. Wat mis ik hier? Bedankt!
Antwoord
TL; DR; Het transactielogboek bevat alle informatie die nodig is om elke transactie opnieuw te maken of ongedaan te maken, afhankelijk van of het een vastleggingsrecord voor die transactie bevat of niet.
In SQL-databases wordt transactie-atomiciteit het vaakst geïmplementeerd met opschrijflogboekregistratie (wat betekent dat de transactielogboekvermeldingen voordat de feitelijke tabellen en indexen worden bijgewerkt).
Querys in de strikte zin van het woord, dat wil zeggen SELECT
statements en andere leesbewerkingen die de databasestatus niet veranderen, worden niet gelogd omdat er niets is vast te leggen of terug te draaien, en als zodanig is het concept van atomiciteit hier niet echt van toepassing, tenminste op DBMS-niveau. De toepassing die queryresultaten gebruikt, moet mogelijk atomiciteit afdwingen door de resultaten van eerdere querys te negeren als een van de volgende querys mislukt en het terugdraaien veroorzaakt.
Wanneer DML-instructies (INSERT
, UPDATE
, DELETE
, MERGE
) en andere instructies die de databasestatus veranderen, get uitgevoerd, worden de aangebrachte wijzigingen eerst in het write-ahead log (WAL) geschreven. Als alle instructies slagen en een commit (expliciet of impliciet) wordt uitgegeven, wordt dit feit ook vastgelegd in de WAL en wordt het logboek bewaard. Dit maakt de veranderingen duurzaam. Ze kunnen op een later tijdstip worden weggeschreven naar de feitelijke tabel- en indexsegmenten, tijdens een checkpoint of logboekherhaling.
Als een van de instructies echter mislukt, zou er geen vastleggingsrecord in het logboek staan voor deze transactie, en het DBMS zal tot dusver gemaakte tabel- en indexwijzigingen ongedaan maken met behulp van de voorgaande logboekrecords van die transactie.
Evenzo, als het DBMS-proces crasht of de stroom uitvalt, zal er geen een vastleggingsrecord voor de transactie tijdens de vlucht, en de tabel- of indexwijzigingen die mogelijk al zijn vastgehouden, worden ongedaan gemaakt tijdens het opnieuw afspelen van het logboek.
Opmerkingen
- Dit is niet ' t correct: " Querys in de strikte zin van het woord, dat wil zeggen SELECT-instructies en andere leesbewerkingen die de databasestatus niet veranderen, worden niet gelogd omdat er niets is om vast te leggen of terug te draaien " – afhankelijk van je database-instellingen kan zelfs een SELECT een impliciete tr starten antwoord. brentozar.com/archive/2018/02/…
- I ' m zeg niet dat ' niet onder transactiecontrole staan, ik ' m zeg dat, aangezien ze dat wel zijn niets veranderen, ze zijn niet gelogd.
Antwoord
Een transactie is atomair wanneer deze is ingekapseld zoals this:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837; UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
In dat geval zullen beide updates op de twee afzonderlijke tabellen samen vastleggen, of ze zullen samen terugdraaien (mislukken). dit is de kleinste eenheid van een transactie die zal worden vastgelegd.
Als u echter later probeert een afzonderlijke zoekopdracht uit te voeren buiten dat bereik, zou dat een afzonderlijke transactie zijn.
Als je zoiets als dit probeert:
BEGIN TRAN UPDATE dbo.Users SET Reputation = Reputation + 1 WHERE Id = 26837;
En dan doe je in je applicatie andere soorten werk, zoals C # code, en kom dan terug naar de database later en doe dit:
UPDATE dbo.Posts SET Score = Score + 1 WHERE Id = 227563; COMMIT
Dan zullen zowel de eerdere gebruikersupdate als je volgende postsupdate zowel slagen, of mislukken, samen.
In het echte leven kun je een transactie echter niet openhouden zoals dat voor een langere tijd omdat je andere mensen blokkeert om werk in de database te doen. Daarom zie je vaak advies als: “Houd uw transactie kort en krachtig”, wat betekent: instappen, uw werk afronden en weer weggaan. Houd transacties niet expliciet open.
Reacties
- Een transactie is altijd atomisch, isn ' niet?
- Ja, maar afhankelijk van uw database-instellingen kunnen impliciete transacties zijn ingeschakeld – wat betekent dat u ' re een BEGIN TRAN krijgen, zelfs als je er niet ' om vraagt. Dat verschilt per leverancier – ik hoor bijvoorbeeld dat Oracle standaard de impliciete transacties gebruikt, terwijl SQL Server dat niet doet.U zou kunnen DENKEN dat u ' slechts één transactie ontvangt als u afkomstig bent van een Oracle-achtergrond, terwijl u misschien verschillende verschillende transacties krijgt in SQL Server – die elk atomisch zouden zijn.