Analyse der vier Transaktionsisolationsstufen in MySQL anhand von Beispielen

Analyse der vier Transaktionsisolationsstufen in MySQL anhand von Beispielen

Vorwort

Um bei Datenbankoperationen die Richtigkeit des gleichzeitigen Datenlesens effektiv sicherzustellen, wird eine Transaktionsisolationsebene vorgeschlagen. Es gibt 4 Isolationsebenen für Datenbanktransaktionen. Ich werde im Folgenden nicht näher darauf eingehen. Schauen wir uns die ausführliche Einführung an.

Es gibt vier Isolationsebenen für Datenbanktransaktionen:

  • Nicht festgeschriebenes Lesen: Dirty Reads sind zulässig, was bedeutet, dass Daten gelesen werden dürfen, die durch nicht festgeschriebene Transaktionen in anderen Sitzungen geändert wurden.
  • Festgeschriebene Daten lesen: Es können nur festgeschriebene Daten gelesen werden. Diese Ebene ist die Standardeinstellung für die meisten Datenbanken, z. B. Oracle.
  • Wiederholbares Lesen: Wiederholbares Lesen. Alle Abfragen innerhalb derselben Transaktion sind zu Beginn der Transaktion konsistent. Dies ist die Standardebene für InnoDB. Im SQL-Standard werden durch diese Isolationsebene nicht wiederholbare Lesevorgänge eliminiert, Phantomlesevorgänge sind jedoch weiterhin vorhanden.
  • Serialisierbar: Ein vollständig serialisierter Lesevorgang. Für jeden Lesevorgang ist eine gemeinsame Sperre auf Tabellenebene erforderlich. Lesen und Schreiben blockieren sich gegenseitig.

Freunde, die mit dem Konzept der Transaktionsisolation noch nicht vertraut sind, können durch die obige Lehrbuchdefinition verwirrt sein. Im Folgenden werden die vier Isolationsebenen anhand spezifischer Beispiele erläutert.

Zuerst erstellen wir eine Benutzertabelle:

CREATE TABLE-Benutzer (
 `id` int(11) NICHT NULL AUTO_INCREMENT,
 `name` varchar(255) NICHT NULL,
 Primärschlüssel (`id`),
 EINZIGARTIGER `uniq_name` MIT BTREE (Name)
) ENGINE=`InnoDB` AUTO_INCREMENT=10 STANDARD-ZEICHENSATZ utf8 COLLATE utf8_general_ci;

Isolationsebene „Nicht festgeschrieben lesen“

Wir setzen zunächst die Isolationsstufe für Transaktionen auf „Commit lesen“:

mysql> Isolationsebene für Sitzungstransaktionen festlegen, nicht festgeschriebenes Lesen;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> wähle @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| LESEN-UNCOMMITTED |
+------------------------+
1 Zeile im Satz (0,00 Sek.)

Unten öffnen wir zwei Terminals, um Transaktion eins und Transaktion zwei zu simulieren. PS: Operation eins und Operation zwei sollen in chronologischer Reihenfolge ausgeführt werden.

Transaktion 1

mysql> Transaktion starten; # Vorgang 1
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> in Benutzer(name) Werte('ziwenxie') einfügen; # Vorgang 3
Abfrage OK, 1 Zeile betroffen (0,05 Sek.)

Transaktion 2

mysql> Transaktion starten; # Vorgang 2
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> select * from user; # Vorgang 4
+----+----------+
| Ich würde | Name |
+----+----------+
| 10 | ziwenxie |
+----+----------+
1 Zeile im Satz (0,00 Sek.)

Aus den obigen Ausführungsergebnissen ist klar ersichtlich, dass wir auf der Ebene „Read Uncommit“ in Transaktion 1 möglicherweise Daten lesen, die in Transaktion 2 nicht committet wurden. Dies ist ein „Dirty Read“.

Isolationsstufe „Commited lesen“

Das oben genannte Dirty-Read-Problem kann gelöst werden, indem die Isolationsebene auf „Commit“ gesetzt wird.

mysql> Isolationsebene für Sitzungstransaktionen festlegen, Lesen festgeschrieben;

Transaktion 1

mysql> start transaction; # Operation 1 Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> select * from user; # Operation drei+----+----------+
| Ich würde | Name |
+----+----------+
| 10 | ziwenxie |
+----+----------+
1 Zeile im Satz (0,00 Sek.)
mysql> select * from user; # Operation 5. Die Änderung der Operation 4 wirkt sich nicht auf Transaktion 1 aus+----+----------+
| Ich würde | Name |
+----+----------+
| 10 | ziwenxie |
+----+----------+
1 Zeile im Satz (0,00 Sek.)
mysql> select * from user; # Operation sieben+----+------+
| Ich würde | Name |
+----+------+
| 10 | lisi |
+----+------+
1 Zeile im Satz (0,00 Sek.)
mysql> commit; # Operation 8 Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

Transaktion 2

mysql> start transaction; # Operation 2 Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> update user set name='lisi' where id=10; # Operation 4 Abfrage OK, 1 Zeile betroffen (0,06 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 1 Warnungen: 0
mysql> commit; # Operation 6 Abfrage OK, 0 Zeilen betroffen (0,08 Sek.)

Obwohl das Problem des Dirty Read gelöst ist, beachten Sie bitte, dass in Operation 7 von Transaktion 1, nachdem Operation 6 von Transaktion 2 festgeschrieben wurde, die von Transaktion 1 in derselben Transaktion zweimal gelesenen Daten unterschiedlich sind. Dies ist das Problem des nicht wiederholbaren Lesens. Dieses Problem kann durch die Verwendung des wiederholbaren Lesens der dritten Transaktionsisolationsebene gelöst werden.

Wiederholbare Leseisolationsebene

Die Standardtransaktionsisolationsebene der Innodb-Speicher-Engine von MySQL ist die wiederholbare Leseisolationsebene, daher müssen wir keine zusätzlichen Einstellungen vornehmen.

Transaktion 1

mysql> starte tansactoin; # Operation 1mysql> select * from user; # Operation 5+----+----------+
| Ich würde | Name |
+----+----------+
| 10 | ziwenxie |
+----+----------+
1 Zeile im Satz (0,00 Sek.)
mysql> commit; # Vorgang 6 Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> select * from user; # Operation sieben+----+------+
| Ich würde | Name |
+----+------+
| 10 | lisi |
+----+------+
1 Zeile im Satz (0,00 Sek.)

Transaktion 2

mysql> start tansactoin; # Vorgang 2mysql> update user set name='lisi' where id=10; # Vorgang 3Abfrage OK, 1 Zeile betroffen (0,00 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 1 Warnungen: 0
mysql> commit; # Vorgang 4

In Operation 5 von Transaktion 1 haben wir das Update von Transaktion 2 in Operation 3 nicht gelesen. Wir können die aktualisierten Daten erst nach dem Commit lesen.

Löst Innodb Phantom-Lesevorgänge?

Tatsächlich können Phantom-Lesevorgänge auf RR-Ebene auftreten. Die InnoDB-Engine behauptet offiziell, dass dieses Problem durch die Verwendung der MVCC-Mehrversions-Parallelitätskontrolle gelöst wird. Lassen Sie uns überprüfen, ob InnoDB Phantom-Lesevorgänge wirklich löst.

Zur Vereinfachung der Anzeige habe ich die Benutzertabelle oben geändert:

mysql> Tabelle ändern, Benutzer, Gehalt hinzufügen, int(11);
Abfrage OK, 0 Zeilen betroffen (0,51 Sek.)
Datensätze: 0 Duplikate: 0 Warnungen: 0
mysql> vom Benutzer löschen;
Abfrage OK, 1 Zeile betroffen (0,07 Sek.)
mysql> in Benutzer einfügen (Name, Gehalt) Wert ('ziwenxie', 88888888);
Abfrage OK, 1 Zeile betroffen (0,07 Sek.)
mysql> wähle * vom Benutzer aus;
+----+----------+----------+
| ID | Name | Gehalt |
+----+----------+----------+
| 10 | ziwenxie | 88888888 |
+----+----------+----------+
1 Zeile im Satz (0,00 Sek.)

Transaktion 1

mysql> start transaction; # Operation 1 Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> update user set salary='4444'; # Operation sechs betraf tatsächlich zwei Zeilen. Hat sie das Phantomlesen nicht gelöst?
Abfrage OK, 2 Zeilen betroffen (0,00 Sek.)
Übereinstimmende Zeilen: 2 Geändert: 2 Warnungen: 0
mysql> select * from user; # Operation 7, Innodb löst das Phantomlesen nicht vollständig +----+----------+--------+
| ID | Name | Gehalt |
+----+----------+--------+
| 10 | ziwenxie | 4444 |
| 11 | Zhangsan | 4444 |
+----+----------+--------+
2 Zeilen im Satz (0,00 Sek.)
mysql> commit; # Operation 8 Abfrage OK, 0 Zeilen betroffen (0,04 Sek.)

Transaktion 2

mysql> start transaction; # Operation 2 Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
mysql> insert into user(name, salary) value('zhangsan', '666666'); # Vorgang 4 Abfrage OK, 1 Zeile betroffen (0,00 Sek.)
mysql> commit; # Operation 5 Abfrage OK, 0 Zeilen betroffen (0,04 Sek.)

Aus dem obigen Beispiel können wir ersehen, dass Innodb Phantom-Lesevorgänge nicht wie offiziell behauptet löst. Das obige Szenario kommt jedoch nicht sehr häufig vor und es besteht kein Grund zur Sorge.

Serialisierbare Isolationsebene

Alle Transaktionen werden seriell und auf der höchsten Isolationsebene ausgeführt. Phantom-Lesevorgänge finden nicht statt. Die Leistung ist sehr schlecht und wird in der tatsächlichen Entwicklung selten verwendet.

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels Ihnen bei Ihrem Studium oder Ihrer Arbeit helfen kann. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • Tiefgreifendes Verständnis der vier Isolationsebenen von MySQL
  • Detaillierte Erläuterung der vier Transaktionsisolationsebenen in MySQL
  • Detaillierte Erläuterung des MySQL-Isolationsebenen-Operationsprozesses (cmd)
  • Beispielanalyse des Prinzips der MySQL-Transaktionsisolationsebene
  • Detaillierte Erläuterung des Implementierungsprinzips der Transaktionsisolationsstufe in MySQL
  • Detaillierte Erklärung und Beispiele der MySQL-Isolationsebene

<<:  So erstellen Sie schnell eine statische Website in der Alibaba Cloud

>>:  So ändern Sie die Konfiguration von „create-react-app“, ohne „eject“ zu verwenden

Artikel empfehlen

CSS3 verwendet var()- und calc()-Funktionen, um Animationseffekte zu erzielen

Wissenspunkte in der Vorschau anzeigen. Animation...

Flussdiagramm für den Webserverzugriff auf HTTP und HTTP-Zusammenarbeit

Ein Webserver kann mehrere Websites mit unabhängi...

Vue3 AST Parser-Quellcode-Analyse

Inhaltsverzeichnis 1. Generieren Sie einen abstra...

MySQL-Lernprogramm Clustered Index

Das Clustering ist eigentlich relativ zur InnoDB-...

Ein Artikel bringt Ihnen bei, sauberen JavaScript-Code zu schreiben

Inhaltsverzeichnis 1. Variablen Verwenden Sie aus...

Detaillierter Prozess der FastAPI-Bereitstellung auf Docker

Docker-Lernen https://www.cnblogs.com/poloyy/p/15...