Detaillierte Erläuterung der Transaktionsisolationsebenen in den MySql-Studiennotizen

Detaillierte Erläuterung der Transaktionsisolationsebenen in den MySql-Studiennotizen

Hintergrund

Wenn wir über Transaktionen sprechen, sollte jeder damit vertraut sein. Bei der Entwicklung mit MySQL-Datenbanken verwenden wir normalerweise Transaktionen. Ein klassisches Beispiel ist die Geldüberweisung. Sie möchten beispielsweise 50 Yuan an Xiao Ming überweisen, haben aber zu diesem Zeitpunkt nur 50 Yuan auf Ihrer Bankkarte.

Im Codeprogramm für den Überweisungsprozess gibt es eine Reihe von Vorgängen, z. B. das Überprüfen des Kontostands, das Hinzufügen und Abziehen des Kontostands, das Aktualisieren des Kontostands usw. Diese Vorgänge müssen zusammen verarbeitet werden. Andernfalls wäre es nicht ein Chaos, wenn das Programm die Überprüfung abgeschlossen hat und die 50 Yuan noch auf dem Konto sind und das Geld dann an einen anderen Freund überwiesen wird. Wenn die Bank dies auch abwickelt und die Datenkonsistenz des gesamten Prozesses nicht gewährleistet ist, wäre das nicht ein Chaos? Hier kommen „Transaktionen“ ins Spiel.

Transaktionseinführung

Einfach ausgedrückt soll eine Transaktion sicherstellen, dass eine Reihe von Datenbankoperationen entweder alle erfolgreich ausgeführt werden oder alle fehlschlagen. In MySQL ist die Transaktionsunterstützung auf Engine-Ebene (InnoDB) implementiert. Wir wissen, dass MySQL ein System ist, das mehrere Engines unterstützt, aber nicht alle Engines unterstützen Transaktionen. Beispielsweise unterstützt die native MyISAM-Engine von MySQL keine Transaktionen, was einer der wichtigen Gründe ist, warum MyISAM durch InnoDB ersetzt wurde.

In diesem Artikel werden wir am Beispiel von InnoDB über einige Implementierungen der MySQL-Transaktionsunterstützung sprechen und entsprechende praktische Vorschläge basierend auf den Prinzipien geben. Durch diese Erklärungen können Sie Ihr Verständnis der Prinzipien von MySQL-Transaktionen vertiefen.

Transaktionsisolationsebene

Wenn es um Transaktionen geht, denken Sie bestimmt an ACID (Atomicity, Consistency, Isolation, Durability). Lassen Sie uns über das I sprechen, das für „Isolation“ steht.

Wenn mehrere Transaktionen gleichzeitig in einer Datenbank ausgeführt werden, können Dirty Reads, nicht wiederholbare Reads und Phantom Reads auftreten. Um diese Probleme zu lösen, wurde das Konzept der „Isolationsebene“ eingeführt.

Bevor Sie über Isolationsstufen sprechen, müssen Sie zunächst wissen, dass die Effizienz umso geringer ist, je strenger Ihre Isolation ist. Daher müssen wir oft ein Gleichgewicht zwischen beiden finden. Zu den SQL-Standardtransaktionsisolierungsebenen zählen: „Read Uncommitted“, „Read Committed“, „Repeatable Read“ und „Serializable“. Hier sind die Erklärungen der Reihe nach für Sie:

  • „Nicht festgeschriebenes Lesen“ bedeutet, dass die von einer Transaktion vorgenommenen Änderungen für andere Transaktionen sichtbar sind, wenn sie nicht festgeschrieben ist.
  • „Commit lesen“ bedeutet, dass die von einer Transaktion vorgenommenen Änderungen nach dem Commit für andere Transaktionen sichtbar sind.
  • Wiederholbares Lesen bedeutet, dass die während der Ausführung einer Transaktion angezeigten Daten immer mit den Daten übereinstimmen, die beim Start der Transaktion angezeigt wurden. Natürlich sind auf der Isolationsebene für wiederholbares Lesen nicht festgeschriebene Änderungen für andere Transaktionen nicht sichtbar.
  • Serialisierung bedeutet, wie der Name schon sagt, dass für dieselbe Datensatzzeile durch „Schreiben“ eine „Schreibsperre“ und durch „Lesen“ eine „Lesesperre“ hinzugefügt wird. Wenn ein Lese-/Schreibsperrenkonflikt auftritt, muss die später aufgerufene Transaktion warten, bis die vorherige Transaktion abgeschlossen ist, bevor sie mit der Ausführung fortfahren kann.

Unter ihnen sind „Read Committed“ und „Repeatable Read“ schwieriger zu verstehen, daher möchte ich diese Isolationsebenen anhand eines Beispiels veranschaulichen. Angenommen, die Datentabelle t_student enthält nur eine Spalte und der Wert einer Zeile ist 21. Im Folgenden sehen Sie das Verhalten bei der Ausführung zweier Transaktionen in chronologischer Reihenfolge.

mysql> Tabelle erstellen t_student(Alter int) Engine=InnoDB;
mysql> einfügen in t_student(Alter) Werte(21);

Was sind die unterschiedlichen Rückgabeergebnisse von Transaktion A unter verschiedenen Isolationsstufen? Das heißt, was sind die Rückgabewerte von V1, V2 und V3 in der Abbildung? Wenn die Isolationsebene auf „Read Uncommitted“ eingestellt ist, beträgt der Wert von V1 22. Obwohl Transaktion B zu diesem Zeitpunkt noch nicht festgeschrieben wurde, ist das Ergebnis für A sichtbar. Daher sind V2 und V3 auch 22.

Wenn die Isolationsebene „Read Committed“ ist, beträgt V1 21 und V2 22. Die Aktualisierungen der Transaktion B sind für A erst sichtbar, nachdem sie festgeschrieben wurde. Daher beträgt der Wert von V3 ebenfalls 22.

Wenn die Isolationsebene „wiederholbares Lesen“ ist, betragen V1 und V2 21 und V3 22. Der Grund, warum V2 immer noch 21 ist, besteht darin, dass es diesem Prinzip folgt: Die Daten, die die Transaktion während der Ausführung sieht, müssen konsistent sein.

Wenn die Isolationsebene „Serialisierung“ ist, wird Transaktion B gesperrt, wenn sie „21 in 22 ändern“ ausführt. Die Ausführung von Transaktion B kann erst fortgesetzt werden, nachdem Transaktion A festgeschrieben wurde. Aus Sicht von A betragen die Werte von V1 und V2 also 21 und der Wert von V3 ist 22.

Bei der Implementierung wird eine Ansicht in der Datenbank erstellt und das logische Ergebnis der Ansicht als Grundlage für den Zugriff verwendet. Unter der Isolationsebene „wiederholbares Lesen“ wird diese Ansicht beim Start der Transaktion erstellt und während der gesamten Transaktion verwendet.

In der Isolationsebene „Read Committed“ wird diese Ansicht zu Beginn jeder SQL-Anweisungsausführung erstellt. Hierbei ist zu beachten, dass die Isolationsebene „Read Uncommitted“ den aktuellsten Wert im Datensatz direkt und ohne das Konzept einer Ansicht zurückgibt, während die Isolationsebene „serialisierbar“ Sperren direkt verwendet, um parallele Zugriffe zu vermeiden.

Es ist ersichtlich, dass das Datenbankverhalten bei verschiedenen Isolationsebenen unterschiedlich ist. Die Standardisolationsstufe der Oracle-Datenbank ist eigentlich „Read Committed“. Daher müssen Sie bei einigen von Oracle nach MySQL migrierten Anwendungen, um die Konsistenz der Datenbankisolationsstufe sicherzustellen, daran denken, die Isolationsstufe von MySQL auf „Read Committed“ einzustellen.

Die Konfigurationsmethode besteht darin, den Wert des Startparameters „Transaction-Isolation“ auf READ-COMMITTED zu setzen. Sie können „showvariables“ verwenden, um den aktuellen Wert anzuzeigen.

mysql> Variablen wie „transaction_isolation“ anzeigen;

Im Allgemeinen ist die Existenz sinnvoll. Jede Isolationsebene hat ihr eigenes Nutzungsszenario und sollte basierend auf Ihrer eigenen Geschäftssituation bestimmt werden. Manche Leute fragen sich vielleicht, wann ein Szenario mit „wiederholbarem Lesen“ erforderlich ist? Sehen wir uns eine Fallstudie zur Logik der Datenkorrektur an.

Angenommen, Sie verwalten eine Bankkontotabelle, wobei in einer Tabelle der Kontostand am Ende jedes Monats und in einer anderen Tabelle die Rechnungsdetails gespeichert sind. Zu diesem Zeitpunkt müssen Sie eine Datenkorrektur durchführen, das heißt, feststellen, ob die Differenz zwischen dem Saldo des Vormonats und dem aktuellen Saldo mit den Rechnungsdetails dieses Monats übereinstimmt. Sie müssen hoffen, dass selbst wenn ein Benutzer während des Korrekturlesevorgangs eine neue Transaktion durchführt, Ihre Korrekturleseergebnisse dadurch nicht beeinträchtigt werden. Zu diesem Zeitpunkt ist es praktisch, die Isolationsstufe „wiederholbares Lesen“ zu verwenden. Die Ansicht beim Start einer Transaktion kann als statisch betrachtet werden und wird nicht von Aktualisierungen anderer Transaktionen beeinflusst.

Implementierung der Transaktionsisolation

Nachdem wir nun die Transaktionsisolationsebene verstanden haben, schauen wir uns an, wie die Transaktionsisolierung implementiert wird. Hier erklären wir „wiederholbares Lesen“ im Detail. Tatsächlich zeichnet in MySQL jeder Datensatz einen Rollback-Vorgang auf, wenn er aktualisiert wird. Der neueste Wert im Datensatz kann verwendet werden, um durch einen Rollback-Vorgang den Wert des vorherigen Status abzurufen.

Angenommen, ein Wert wird nacheinander von 1 in 2, 3 und 4 geändert. Das Undo-Protokoll enthält einen Eintrag ähnlich dem folgenden:

Der aktuelle Wert ist 4, aber bei der Abfrage dieses Datensatzes haben Transaktionen, die zu unterschiedlichen Zeiten gestartet wurden, unterschiedliche Leseansichten. Wie in der Abbildung gezeigt, lauten die Werte dieses Datensatzes in den Ansichten A, B und C jeweils 1, 2 und 4. Derselbe Datensatz kann im System mehrere Versionen haben, was der Multi-Version Concurrency Control (MVCC) der Datenbank entspricht. Um für die Lese-Ansicht A 1 zu erhalten, müssen Sie alle Rollback-Operationen in der Abbildung nacheinander ausführen, um den aktuellen Wert zu erhalten.

Gleichzeitig werden Sie feststellen, dass selbst wenn es eine andere Transaktion gibt, die 4 auf 5 ändert, diese Transaktion nicht mit den Transaktionen in Konflikt gerät, die den Leseansichten A, B und C entsprechen.
Manche Leute fragen sich vielleicht: „Das Rollback-Protokoll kann nicht ewig aufbewahrt werden. Wann sollte es gelöscht werden?“ Natürlich werden sie gelöscht, wenn sie nicht benötigt werden. Mit anderen Worten, das System bestimmt, dass die Rollback-Protokolle gelöscht werden, wenn keine Transaktion diese Rollback-Protokolle verwenden muss.

Die Frage ist also, wann wird es nicht mehr benötigt? Dies ist der Fall, wenn im System keine Lese-Ansicht vorhanden ist, die vor diesem Rollback-Protokoll liegt.

Lassen Sie uns auf Grundlage der obigen Erklärung erörtern, warum es empfehlenswert ist, die Verwendung langer Transaktionen möglichst zu vermeiden.

Zunächst einmal bedeuten lange Transaktionen, dass es im System sehr alte Transaktionsansichten gibt. Da diese Transaktionen jederzeit auf alle Daten in der Datenbank zugreifen können, müssen vor dem Festschreiben der Transaktion alle Rollback-Datensätze, die sie in der Datenbank verwenden kann, beibehalten werden, was zu einer großen Menge an Speicherplatz führt.

In MySQL 5.5 und früheren Versionen wird das Rollback-Protokoll zusammen mit dem Datenwörterbuch in der ibdata-Datei abgelegt. Selbst wenn die lange Transaktion schließlich festgeschrieben und das Rollback-Segment bereinigt wird, wird die Datei nicht kleiner. Ich habe Bibliotheken mit nur 10 GB Daten und 100 GB Rollback-Segmenten gesehen. Am Ende musste die gesamte Bibliothek neu erstellt werden, um die Rollback-Segmente zu bereinigen.
Zusätzlich zu den Auswirkungen auf das Rollback-Segment belegen lange Transaktionen auch Sperrressourcen und können auch zum Absturz der gesamten Datenbank führen.

Transaktionsstartmodus

Die oben genannten Long-Positionen bergen diese potenziellen Risiken und es wird natürlich empfohlen, sie so weit wie möglich zu vermeiden. Tatsächlich verwenden Geschäftsentwickler lange Transaktionen oft nicht absichtlich, sondern meist aufgrund von Missbrauch. Es gibt mehrere Möglichkeiten, eine MySQL-Transaktion zu starten:

  1. Starten Sie explizit eine Transaktionsanweisung, beginnen oder starten Sie die Transaktion. Die entsprechende Commit-Anweisung lautet „Commit“ und die entsprechende Rollback-Anweisung lautet „Rollback“.
  2. setze autocommit=0, dieser Befehl schaltet das automatische Commit dieses Threads aus. Dies bedeutet, dass beim Ausführen einer bloßen Select-Anweisung die Transaktion gestartet und nicht automatisch festgeschrieben wird. Diese Transaktion bleibt bestehen, bis Sie aktiv eine Commit- oder Rollback-Anweisung ausführen oder die Verbindung trennen.

Einige Clientverbindungsframeworks führen nach einer erfolgreichen Verbindung standardmäßig den Befehl „set autocommit=0“ aus. Dies führt dazu, dass sich alle nachfolgenden Abfragen in der Transaktion befinden, und wenn es sich um eine lange Verbindung handelt, führt dies zu einer unerwartet langen Transaktion.

Daher wird empfohlen, immer set autocommit=1 zu verwenden und Transaktionen durch explizite Anweisungen zu starten. Einige Entwickler könnten jedoch durch das Problem „eine weitere Interaktion“ beunruhigt sein. Für ein Unternehmen, das häufig Transaktionen verwenden muss, erfordert die zweite Methode nicht die aktive Ausführung von „begin“ zu Beginn jeder Transaktion, wodurch die Anzahl der Anweisungsinteraktionen reduziert wird. Wenn Sie dieses Anliegen haben, wird empfohlen, die Commit-Work- und Chain-Syntax zu verwenden.

Wenn Autocommit 1 ist, wird eine explizit mit „begin“ gestartete Transaktion festgeschrieben, wenn „commit“ ausgeführt wird. Wenn Commit Work and Chain ausgeführt wird, wird die Transaktion festgeschrieben und die nächste Transaktion automatisch gestartet, wodurch auch der Aufwand für die erneute Ausführung der Begin-Anweisung eingespart wird. Der Vorteil besteht darin, dass Sie aus Sicht der Programmentwicklung klar erkennen können, ob sich jede Anweisung in einer Transaktion befindet. Sie können lange Transaktionen in der Tabelle innodb_trx in der Bibliothek information_schema abfragen.

Zusammenfassen

Es geht hauptsächlich um das Phänomen und die Implementierung der Transaktionsisolationsebene von MySQL, analysiert die Risiken langer Transaktionen basierend auf den Implementierungsprinzipien und wie lange Transaktionen auf richtige Weise vermieden werden können. Wenn Sie die Prinzipien dieser Transaktionen verstehen, können Sie die Transaktionsfunktionen von MySQL besser nutzen.

Dies ist das Ende dieses Artikels über MySQL-Studiennotizen und Transaktionsisolationsebenen. Weitere Informationen zu MySQL-Transaktionsisolationsebenen finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Hilfedokument „MySQL-Lernhinweise“
  • MySQL-Lernhinweise: Daten-Engine
  • Grundkenntnisse zu MySQL – Lernhinweise
  • MySQL-Lernhinweise: So fügen Sie Daten hinzu, löschen und ändern sie
  • MySQL-Lernhinweise: Erstellen, Löschen und Ändern von Tabellen
  • Zusammenfassung der MySQL-Lernhinweise
  • Eine Zusammenfassung der MySQL-Studiennotizen von 1.000 Zeilen
  • MySQL-Lernhinweise 5: Tabelle ändern (alter table)
  • MySQL-Lernhinweise 4: Integritätsbeschränkungsfelder
  • MySQL-Lernhinweise 1: Installation und Anmeldung (mehrere Methoden)
  • Vollständige MySQL-Lernhinweise

<<:  Lassen Sie Ihren Text mit dem Marquee-Attribut in HTML tanzen

>>:  Die Beziehung zwischen Webseitenerstellung und Dampfbrötchen (Erfahrungsaustausch)

Artikel empfehlen

JavaScript implementiert kreisförmiges Karussell

In diesem Artikel wird der spezifische JavaScript...

JavaScript zum Erreichen eines einfachen Bildwechsels

In diesem Artikel wird der spezifische Code für J...

js native Wasserfall-Flow-Plugin-Produktion

In diesem Artikel wird der spezifische Code des n...

Erläuterung des HTML-Tabellenlayouts als Beispiel

Die Elemente in einem HTML-Dokument werden hinter...

Drei Möglichkeiten, das horizontale Div-Layout auf beiden Seiten auszurichten

In diesem Artikel werden hauptsächlich drei Metho...

Der Unterschied und die Verwendung von json.stringify() und json.parse()

1. Unterschiede zwischen JSON.stringify() und JSO...

So stellen Sie ein Angular-Projekt mit Docker bereit

Es gibt zwei Möglichkeiten, Angular-Projekte mit ...

Deaktivieren der AutoVervollständigen-Funktion im Eingabefeld

Jetzt können wir ein Eingabeattribut namens „Autov...

4 Möglichkeiten zum Anzeigen von Prozessen in LINUX (Zusammenfassung)

Ein Prozess ist ein Programmcode, der in der CPU ...

Kleines Problem mit dem Abstand zwischen Label und Eingabe im Google Browser

Erst Code, dann Text Code kopieren Der Code lautet...