Transaktionen und Mechanismen zu ihrer Kontrolle

Transaktionen


Eine Transaktion ist eine Folge von Operationen an Daten, die einen Anfang und ein Ende haben.


Eine Transaktion ist eine sequentielle Lese- und Schreiboperation. Das Ende einer Transaktion kann entweder das Speichern von Änderungen (Festschreiben, Festschreiben) oder das Abbrechen von Änderungen (Rollback, Rollback) sein. In Bezug auf die Datenbank besteht eine Transaktion aus einer Reihe von Abfragen, die als einzelne Abfrage behandelt werden.

Transaktionen müssen die ACID-Eigenschaften erfüllen


Atomizität. Eine Transaktion wird entweder vollständig oder gar nicht ausgeführt.

Kohärenz. Am Ende der Transaktion dürfen die den Daten auferlegten Einschränkungen (z. B. Einschränkungen in der Datenbank) nicht verletzt werden. Konsistenz bedeutet, dass das System von einem korrekten Zustand in einen anderen korrekten Zustand übertragen wird.

Isolierung. Gleichzeitig ausgeführte Transaktionen sollten sich nicht gegenseitig beeinflussen, z. B. das Ändern von Daten, die von einer anderen Transaktion verwendet werden. Das Ergebnis paralleler Transaktionen sollte so sein, als ob die Transaktionen nacheinander ausgeführt würden.

Nachhaltigkeit. Nach dem Festschreiben sollten die Änderungen nicht verloren gehen.

Transaktionsprotokoll


Das Protokoll speichert Änderungen, die durch Transaktionen vorgenommen wurden, und stellt die Atomizität und Stabilität der Daten im Falle eines Systemausfalls sicher


Das Protokoll enthält die Werte, die die Daten vor und nach ihrer Änderung durch die Transaktion hatten. Für die Write-Ahead-Protokollstrategie müssen Sie dem Protokoll vor dem Start einen Datensatz der vorherigen Werte und nach Abschluss der Transaktion etwa die endgültigen Werte hinzufügen. Bei einem plötzlichen Systemstopp liest die Datenbank das Protokoll in umgekehrter Reihenfolge und verwirft die durch Transaktionen vorgenommenen Änderungen. Nachdem eine unterbrochene Transaktion aufgetreten ist, führt die Datenbank sie aus und nimmt Änderungen daran im Protokoll vor. Die Datenbank befindet sich zum Zeitpunkt des Fehlers im Status und liest das Protokoll in der direkten Reihenfolge und gibt die durch die Transaktionen vorgenommenen Änderungen zurück. Somit bleiben die Stabilität bereits festgeschriebener Transaktionen und die Atomizität der unterbrochenen Transaktion erhalten.

Es reicht nicht aus, nur fehlerhafte Transaktionen erneut auszuführen, um sie wiederherzustellen.

Ein Beispiel. Der Benutzer hat 500 USD auf dem Konto und der Benutzer beschließt, diese über einen Geldautomaten abzuheben. Es werden zwei Transaktionen ausgeführt. Der erste liest den Wert des Guthabens und gibt dem Benutzer Geld, wenn genügend Guthaben auf dem Guthaben vorhanden ist. Der zweite zieht den erforderlichen Betrag vom Saldo ab. Angenommen, ein System stürzt ab und der erste Vorgang schlägt fehl, und der zweite schlägt fehl. In diesem Fall können wir dem Benutzer kein Geld erneut ausgeben, ohne das System mit einem positiven Saldo in den ursprünglichen Zustand zurückzusetzen.

Isolationsstufen


Lesen Sie Committed


Das Problem bei einem Dirty Read ist, dass eine Transaktion das Zwischenergebnis einer anderen Transaktion lesen kann.

Ein Beispiel. Der Anfangswert des Guthabens beträgt 0 USD. T1 erhöht den Kontostand um 50 USD. T2 liest den Kontostand (50 USD). T1 bricht die Änderungen ab und endet. T2 setzt die Ausführung mit falschen Bilanzdaten fort.

Die Lösung ist Read Committed, das das Lesen von durch eine Transaktion geänderten Daten verbietet. Wenn Transaktion A einen Datensatz geändert hat, muss Transaktion B beim Zugriff auf diese Daten auf Transaktion A warten.

Wiederholbares Lesen


Das Problem verlorener Änderungen (verlorene Updates). T1 speichert Änderungen gegenüber Änderungen an T2.

Ein Beispiel. Der anfängliche Kontostand beträgt 0 USD, und zwei Transaktionen füllen gleichzeitig den Kontostand auf. T1 und T2 lesen einen Saldo von 0 USD. Dann addiert T2 $ 200 zu $ ​​0 und speichert das Ergebnis. T1 addiert $ 100 zu $ ​​0 und speichert das Ergebnis. Das Gesamtergebnis ist 100 US-Dollar statt 300 US-Dollar.

Nicht wiederholbares Leseproblem. Das wiederholte Lesen derselben Daten gibt unterschiedliche Werte zurück.

Ein Beispiel. T1 liest einen Kontostand von $ 0. Dann addiert T2 $ 50 zum Kontostand und endet. T1 liest die Daten erneut und stellt eine Abweichung vom vorherigen Ergebnis fest.

Wiederholbares Lesen stellt sicher, dass wiederholtes Lesen das gleiche Ergebnis liefert. Von einer Transaktion gelesene Daten dürfen in anderen nicht geändert werden, bis die Transaktion abgeschlossen ist. Wenn Transaktion A einen Datensatz gelesen hat, muss Transaktion B beim Zugriff auf diese Daten auf Transaktion A warten.

Ordentliches Lesen (serialisierbar)


Phantom liest Zwei Abfragen, die Daten nach bestimmten Bedingungen auswählen, geben unterschiedliche Werte zurück.

Ein Beispiel. T1 fragt nach der Anzahl aller Benutzer, deren Guthaben größer als 0 USD, aber kleiner als 100 USD ist. T2 subtrahiert 1 US-Dollar von einem Benutzer mit einem Kontostand von 101 US-Dollar. T1 führt die Anforderung erneut aus.

Ordentliches Lesen (serialisierbar). Transaktionen werden vollständig sequentiell ausgeführt. Es ist verboten, Datensätze zu aktualisieren und hinzuzufügen, die den Bedingungen der Anforderung unterliegen. Wenn Transaktion A Daten aus der gesamten Tabelle angefordert hat, wird die gesamte Tabelle für den Rest der Transaktionen bis zur Transaktion A eingefroren.

Scheduler


Legt die Reihenfolge fest, in der Vorgänge in parallelen Transaktionen ausgeführt werden sollen


Bietet eine bestimmte Isolationsstufe. Wenn das Ergebnis von Operationen nicht von ihrer Reihenfolge abhängt, sind solche Operationen austauschbar (durchlässig). Befehle werden gelesen und Operationen an verschiedenen Daten ausgeführt. Lese- / Schreib- und Schreib-Schreib-Operationen sind nicht kommutativ. Die Aufgabe des Schedulers besteht darin, Operationen zu wechseln, die von parallelen Transaktionen ausgeführt werden, so dass das Ergebnis der Ausführung der sequentiellen Ausführung von Transaktionen entspricht.

Parallelitätskontrollmechanismen


Optimistisch basierend auf Konflikterkennung und -lösung, pessimistisch basierend auf Konfliktverhütung


Mit einem optimistischen Ansatz verfügen mehrere Benutzer über Kopien der Daten. Der erste, der die Bearbeitung abgeschlossen hat, speichert die Änderungen, der Rest muss die Änderungen zusammenführen. Ein optimistischer Algorithmus lässt das Auftreten eines Konflikts zu, das System muss sich jedoch von dem Konflikt erholen.

Mit einem pessimistischen Ansatz verhindert der erste Benutzer, der Daten erfasst, dass andere Daten empfangen. Wenn Konflikte selten sind, ist es ratsam, eine optimistische Strategie zu wählen, da diese ein höheres Maß an Parallelität bietet.

Verriegeln


Wenn eine Transaktion Daten blockiert hat, muss der Rest der Transaktion beim Zugriff auf die Daten auf die Daten zugreifen.


Ein Block kann einer Datenbank, Tabelle, Zeile oder einem Attribut überlagert werden. Shared Lock (Shared Lock) kann denselben Daten von mehreren Transaktionen auferlegt werden, ermöglicht das Lesen aller Transaktionen (einschließlich auferlegter Transaktionen), verhindert Änderungen und die exklusive Erfassung. Die exklusive Sperre kann nur von einer Transaktion auferlegt werden, erlaubt alle Aktionen der auferlegten Transaktion und verbietet alle Aktionen der übrigen.

Ein Deadlock ist eine Situation, in der sich Transaktionen im Standby-Modus befinden und auf unbestimmte Zeit andauern


Ein Beispiel. Die erste Transaktion wartet auf die Freigabe der von der zweiten erfassten Daten, während die zweite auf die Freigabe der von der ersten erfassten Daten wartet.

Eine optimistische Lösung des Deadlock-Problems ermöglicht das Auftreten eines Deadlocks, stellt dann jedoch das System wieder her, indem eine der am Deadlock beteiligten Transaktionen zurückgesetzt wird


Mit einer bestimmten Häufigkeit wird nach Deadlocks gesucht. Eine der Erkennungsmethoden ist die Zeit, dh zu berücksichtigen, dass ein Deadlock aufgetreten ist, wenn die Transaktion zu lange dauert. Wenn ein Deadlock gefunden wird, wird eine der Transaktionen zurückgesetzt, wodurch andere am Deadlock beteiligte Transaktionen abgeschlossen werden können. Die Wahl des Opfers kann auf dem Wert der Transaktionen oder deren Dienstalter basieren (Wait-Die- und Wound-Wait-Systeme).

Jeder Transaktion T ist ein Zeitstempel TS zugeordnet , der die Startzeit der Transaktion enthält.

Wait-Die

Wenn TS (Ti) < TS (Tj) ist , wartet Ti , andernfalls rollt Ti zurück und beginnt erneut mit demselben Zeitstempel.

Wenn eine junge Transaktion eine Ressource erfasst hat und eine ältere dieselbe Ressource anfordert, kann eine ältere Transaktion erwartet werden. Wenn eine ältere Transaktion eine Ressource erfasst hat, wird eine junge Transaktion, die diese Ressource anfordert, zurückgesetzt.

Wund warten.

Wenn TS (Ti) < TS (Tj) ist , rollt Tj zurück und beginnt erneut mit demselben Zeitstempel, andernfalls wartet Ti .

Wenn eine jüngere Transaktion eine Ressource erfasst hat und eine ältere Transaktion dieselbe Ressource anfordert, wird die junge Transaktion zurückgesetzt. Wenn eine ältere Transaktion die Ressource erfasst hat, kann eine jüngere Transaktion, die diese Ressource anfordert, warten. Die auf dem Dienstalter basierende Auswahl des Opfers verhindert Deadlocks, setzt jedoch Transaktionen zurück, die sich nicht in einem ineinandergreifenden Zustand befinden. Das Problem ist, dass Transaktionen viele Male zurückgesetzt werden können, weil Eine ältere Transaktion kann eine Ressource für eine lange Zeit halten.

Eine pessimistische Lösung des Problems der Deadlocks ermöglicht es der Transaktion nicht, die Ausführung zu starten, wenn das Risiko eines Deadlocks besteht


Um Deadlocks zu erkennen, wird ein Diagramm erstellt (ein Wartediagramm, ein Wartediagramm), dessen Eckpunkte Transaktionen sind, und die Kanten werden von Transaktionen geleitet, die darauf warten, dass Daten an die Transaktion freigegeben werden, die diese Daten erfasst hat. Es wird angenommen, dass ein Deadlock aufgetreten ist, wenn der Graph geloopt wird. Das Erstellen eines Wartediagramms, insbesondere in verteilten Datenbanken, ist ein teures Verfahren.

Zweiphasiges Sperren - Verhindert Deadlocks, indem alle von der Transaktion zu Beginn der Transaktion verwendeten Ressourcen erfasst und am Ende freigegeben werden


Alle Blockierungsvorgänge müssen vor dem ersten Entsperren erfolgen. Es besteht aus zwei Phasen: der Wachstumsphase, in der die Erfassung der Greifer erfolgt, und der Schrumpfungsphase, in der die Freigabe der Greifer erfolgt. Wenn es nicht möglich ist, eine der Ressourcen zu erfassen, beginnt die Transaktion erneut. Es ist möglich, dass eine Transaktion die erforderlichen Ressourcen nicht erfassen kann, wenn beispielsweise mehrere Transaktionen um dieselben Ressourcen konkurrieren.

Das zweiphasige Festschreiben stellt sicher, dass das Festschreiben auf allen Datenbankreplikaten ausgeführt wird


Jede Datenbank liefert Informationen zu den Daten, die in das Protokoll geändert werden, und entspricht dem Koordinator OK (Abstimmungsphase). Nachdem alle mit OK geantwortet haben, sendet der Koordinator ein Signal, das alle zum Festschreiben verpflichtet. Nach dem Festschreiben des Servers antworten sie mit OK. Wenn mindestens einer nicht mit OK geantwortet hat, sendet der Koordinator ein Signal, um die Änderungen an allen Servern abzubrechen (Abschlussphase).

Zeitstempelmethode


Eine ältere Transaktion wird zurückgesetzt, wenn versucht wird, auf Daten zuzugreifen, die an einer jüngeren Transaktion beteiligt sind


Jeder Transaktion wird ein TS- Zeitstempel zugewiesen, der der Startzeit der Ausführung entspricht. Wenn Ti älter als Tj ist , dann ist TS (Ti) < TS (Tj) .

Wenn eine Transaktion zurückgesetzt wird, wird ihr ein neuer Zeitstempel zugewiesen. Jedes an der Transaktion beteiligte Datenobjekt Q ist mit zwei Bezeichnungen gekennzeichnet. W-TS (Q) ist der Zeitstempel der jüngsten Transaktion, die erfolgreich an Q geschrieben hat. R-TS (Q) ist der Zeitstempel der jüngsten Transaktion, die einen Lesedatensatz über Q abgeschlossen hat.

Wenn die Transaktion T das Lesen von Q- Daten anfordert, sind zwei Optionen möglich.

Wenn TS (T) < W-TS (Q) ist, dh die Daten durch eine jüngere Transaktion aktualisiert wurden, wird die Transaktion T zurückgesetzt.

Wenn TS (T) > = W-TS (Q) ist , wird das Lesen durchgeführt und R-TS (Q) wird MAX (R-TS (Q), TS (T)) .

Wenn die Transaktion T eine Änderung der Daten Q anfordert, sind zwei Optionen möglich.

Wenn TS (T) < R-TS (Q) ist, dh die Daten bereits von einer jüngeren Transaktion gelesen wurden und eine Änderung vorgenommen wird, entsteht ein Konflikt. Transaktion T wird zurückgesetzt.

Wenn TS (T) < W-TS (Q) ist, dh die Transaktion versucht, den neueren Wert zu überschreiben, wird die Transaktion T zurückgesetzt. In anderen Fällen wird die Änderung durchgeführt und W-TS (Q) wird gleich TS (T) .

Es ist keine teure Konstruktion des wartenden Graphen erforderlich. Ältere Transaktionen hängen von neueren ab, daher gibt es keine Schleifen in der Wartespalte. Es gibt keine Deadlocks, da Transaktionen nicht erwartet werden, sondern sofort zurückgesetzt werden. Kaskadierende Rückschläge sind möglich. Wenn Ti zurückgesetzt wird und Tj die Daten liest, die Ti geändert hat, sollte Tj ebenfalls zurückgesetzt werden. Wenn gleichzeitig Tj bereits mitgeteilt wurde, liegt eine Verletzung des Stabilitätsprinzips vor.

Eine Lösung für kaskadierende Rollbacks. Eine Transaktion führt am Ende alle Schreibvorgänge aus, und die verbleibenden Transaktionen müssen auf den Abschluss dieses Vorgangs warten. Transaktionen warten vor dem Lesen auf ein Commit.

Thomas-Schreibregel - Eine Variation der Zeitstempelmethode, bei der Daten, die von einer jüngeren Transaktion aktualisiert wurden, nicht von einer älteren überschrieben werden dürfen


Transaktion T fordert eine Änderung der Daten Q an. Wenn TS (T) < W-TS (Q) ist, dh die Transaktion versucht, einen neueren Wert zu überschreiben, wird die Transaktion T nicht wie bei der Zeitstempelmethode zurückgesetzt.

Source: https://habr.com/ru/post/de446662/


All Articles