Beispielcode für das Testskript für Indizes und Sperren auf den Isolationsebenen RR und RC

Beispielcode für das Testskript für Indizes und Sperren auf den Isolationsebenen RR und RC

Grundlegende Konzepte

Aktueller Lesevorgang und Snapshot-Lesen

In MVCC können Lesevorgänge in zwei Kategorien unterteilt werden: Snapshot-Lesen und aktuelles Lesen. Snapshot liest die sichtbare Version des Datensatzes (möglicherweise eine historische Version) ohne Sperrung. Beim aktuellen Lesevorgang wird die neueste Version des Datensatzes gelesen und der zurückgegebene Datensatz wird gesperrt, um sicherzustellen, dass die Daten vor Ende der Transaktion die neueste Version aufweisen.

Snapshot-Lesen: Ein einfacher Auswahlvorgang ist ein Snapshot-Lesen und ist nicht gesperrt (außer bei Serializable).

Wählen Sie * aus der Tabelle, wo?;

Aktuelles Lesen: Spezielle Lesevorgänge, wie etwa Einfüge-/Aktualisierungs-/Löschvorgänge, sind aktuelle Lesevorgänge und erfordern eine Sperrung.

Wählen Sie * aus der Tabelle, wo? Im Freigabemodus sperren;
Wählen Sie * aus der Tabelle, wobei ? für die Aktualisierung steht;
in Tabellenwerte einfügen();
Tabellensatz aktualisieren? Wo?;
aus Tabelle löschen, wo?;

Isolationsstufe und Sperrmechanismus

  • „Read Uncommitted“ führt zu Dirty Reads und wird nicht berücksichtigt.
  • Read Committed (RC) Beim aktuellen Lesevorgang stellt die RC-Isolationsebene sicher, dass die gelesenen Datensätze gesperrt sind (Gap Locking) und Phantom-Lesevorgänge auftreten können.
  • Wiederholbares Lesen (RR) Beim aktuellen Lesen stellt die RR-Isolationsstufe sicher, dass die gelesenen Datensätze gesperrt sind (Datensatzsperre) und stellt gleichzeitig sicher, dass der Lesebereich gesperrt ist. Neue Datensätze, die die Abfragebedingungen erfüllen, können nicht eingefügt werden (Lückensperre), und es gibt kein Phantomlesephänomen.
  • Alle Lesevorgänge von Serializable werden auf aktuelle Lesevorgänge herabgestuft und es treten Lese-/Schreibkonflikte auf, sodass die Parallelität stark abnimmt und nicht berücksichtigt wird.

Testskripte

-- Grundlegende Bedienung --
--Transaktionsisolationsstufe abfragen, der Standardwert ist RR
Variablen wie „%isolation%“ anzeigen;

-- Setzen Sie die Transaktionsisolationsebene auf RC
Isolationsstufe für Sitzungstransaktionen festlegen, Lesen festgeschrieben;


-- Dateninitialisierung --
beginnen;
Tabelle löschen, wenn Benutzer vorhanden ist;
CREATE TABLE `Benutzer` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `E-Mail` varchar(64) NICHT NULL,
 `Alter` int(11) NICHT NULL,
 `Adresse` varchar(64) NICHT NULL,
 Primärschlüssel (`id`),
 EINZIGARTIGER SCHLÜSSEL `uniq_email` (`E-Mail`),
 SCHLÜSSEL `idx_age` (`Alter`)
);

in den Benutzer (E-Mail, Alter, Adresse) Werte einfügen („[email protected]“, 18, „address1“);
in den Benutzer (E-Mail, Alter, Adresse) Werte einfügen („[email protected]“, 20, „address2“);
in den Benutzer (E-Mail, Alter, Adresse) Werte einfügen („[email protected]“, 20, „address3“);

begehen;
wähle * vom Benutzer;



-- 1. trx_id Beispiel beginnt;
Wählen Sie TRX_ID aus Information_Schema.InnoDB_TRX, wobei TRX_MYSQL_THREAD_ID = Verbindung_ID () ist.
wähle * vom Benutzer;
Wählen Sie TRX_ID aus Information_Schema.InnoDB_TRX, wobei TRX_MYSQL_THREAD_ID = Verbindung_ID () ist.
ENGINE-INNODB-STATUS ANZEIGEN;
Benutzer aktualisieren, Alter = 22, wobei ID = 3;
-- Transaktions-ID abfragen
Wählen Sie TRX_ID aus Information_Schema.InnoDB_TRX, wobei TRX_MYSQL_THREAD_ID = Verbindung_ID () ist.
-- INNODB-Engine-Status. SHOW ENGINE INNODB STATUS;
begehen;

-- 2. Beispiele für wiederholbares und nicht wiederholbares Lesen -- Sitzung 1
Isolationsstufe für Sitzungstransaktionen festlegen, Lesen festgeschrieben;
beginnen;
--session2
Legen Sie die Isolationsstufe für Sitzungstransaktionen fest und erlauben Sie ein wiederholbares Lesen.
beginnen;
--session1
wähle * vom Benutzer;
--session2
wähle * vom Benutzer;
--session3
beginnen;
in den Benutzer (E-Mail, Alter, Adresse) Werte einfügen („[email protected]“, 30, „address4“);
begehen;
-- Session1 ist im RC-Modus, sodass sie die neuen von trx3 übermittelten Daten lesen kann. Wenn Sie ein nicht wiederholbares Lesen nachweisen möchten, sollten Sie „update“ statt „insert“ verwenden.
wähle * vom Benutzer;
begehen;
-- Session2 ist hier RR und liest daher die neuen von trx3 select * from user übermittelten Daten nicht.
begehen;

-- 3. Beispiel für Phantom-Lesen eines Snapshots -- Sitzung1
Legen Sie die Isolationsstufe für Sitzungstransaktionen fest und erlauben Sie ein wiederholbares Lesen.
beginnen;
-- Hier verwenden wir Snapshot Read Select * vom Benutzer;
--session2
beginnen;
in den Benutzer (E-Mail, Alter, Adresse) Werte einfügen („[email protected]“, 30, „address4“);
begehen;
wähle * vom Benutzer;
--session1
select * from user; -- Die Daten von test4@ können hier nicht gelesen werden, da es sich um RR handelt
– Hier erfolgt ein Phantom-Lesevorgang, Einfügen in Benutzerwerte (E-Mail, Alter, Adresse) („[email protected]“, 30, „address4“); – Einfügen schlägt wegen Commit aufgrund eines Konflikts im eindeutigen Index der E-Mail fehl;

-- 4. Aktuelles Phantomlesebeispiel -- RC
--session1
Isolationsstufe für Sitzungstransaktionen festlegen, Lesen festgeschrieben;
beginnen;
-- Hier werden alle Datensätze mit Alter = 20, die die Bedingung erfüllen, gesperrt. Da es sich um RC handelt, gibt es keine GAP-Sperre. Löschen von Benutzer mit Alter = 20;
wähle * vom Benutzer;
--session2
Isolationsstufe für Sitzungstransaktionen festlegen, Lesen festgeschrieben;
beginnen;
-- Da trx1 keine GAP-Sperre hat, können Datensätze mit Alter=20 in Benutzerwerte (E-Mail, Alter, Adresse) eingefügt werden („[email protected]“, 20, „address4“);
select * from user; -- Sie können 4 Daten finden und die gelöschten Daten von trx1 lesen. Da es sich um RC handelt, wurde trx1 nicht übermittelt, sodass es trx2 nicht beeinflusst.
begehen;
--session1
select * from user; -- Sie können die neu eingefügten Daten von trx2 lesen. Obwohl trx1 gerade liest, wird die entsprechende Next-Key-Sperre nicht hinzugefügt, was nicht verhindert, dass die neuen Daten von trx2 eingefügt und festgeschrieben werden.

--RR
--session1
Legen Sie die Isolationsstufe für Sitzungstransaktionen fest und erlauben Sie ein wiederholbares Lesen.
beginnen;
Löschen von Benutzer mit Alter = 20;
wähle * vom Benutzer;
--session2
beginnen;
-- Dies führt zu einer Blockierung, da trx1 bei Alter=20 eine GAP-Sperre hinzufügt. -- Suchen Sie bei einem nicht eindeutigen Index zuerst den ersten Datensatz, der die Abfragekriterien über den Index erfüllt, fügen Sie dem Datensatz eine X-Sperre hinzu, fügen Sie der GAP eine GAP-Sperre hinzu und fügen Sie dann dem Datensatz im gruppierten Primärschlüsselindex eine X-Sperre hinzu;
– Lesen Sie dann den nächsten und wiederholen Sie. Bis der erste Datensatz erreicht ist, der die Bedingungen nicht erfüllt, muss zu diesem Zeitpunkt keine Datensatz-X-Sperre hinzugefügt werden, es ist jedoch weiterhin eine GAP-Sperre erforderlich, und schließlich muss zum Ende zurückgekehrt werden.
in den Benutzer (E-Mail, Alter, Adresse) Werte einfügen („[email protected]“, 20, „address4“);
-- Bis zum Timeout, FEHLER 1205 (HY000): Wartezeit für Sperre überschritten; versuchen Sie, die Transaktion neu zu starten.
-- Wenn Sie jetzt eine Abfrage durchführen, können Sie 3 festgeschriebene Datensätze sehen;
--session1
-- Zurzeit ist nur ein Datensatz sichtbar, die anderen beiden wurden gelöscht. select * from user;
begehen;

-- Eindeutiger Index + RC
--session1
Isolationsstufe für Sitzungstransaktionen festlegen, Lesen festgeschrieben;
beginnen;
Löschen vom Benutzer, bei dem die E-Mail-Adresse „[email protected]“ lautet;
--session2
beginnen;
-- Kann gelesen werden, da trx1 RC ist
Wählen Sie * vom Benutzer, wobei E-Mail = "[email protected]" ist;
-- Versuchen Sie, das Alter dieses Datensatzes zu aktualisieren. Er wird bis zum Timeout blockiert, da E-Mail der einzige Index ist, der von trx1 gesperrt wurde, und der entsprechende Primärschlüsselindex ebenfalls gesperrt wird. -- Beachten Sie, dass die hier verwendete ID = 3 derselbe Zeilendatensatz der E-Mail ist, die in trx1 „Benutzeraktualisierung, Alter festlegen“ = 40 verwendet wird, wobei ID = 3;
--session1
begehen;
--session2
begehen;

-- Kein Index + RC
--session1
Isolationsstufe für Sitzungstransaktionen festlegen, Lesen festgeschrieben;
beginnen;
-- Da das Adressfeld keinen Index hat, sperrt Innodb alle Zeilen, und der MySQL-Server trifft eine Entscheidung und hebt die Sperre auf. delete from user where address = "address3";
--session2
Isolationsstufe für Sitzungstransaktionen festlegen, Lesen festgeschrieben;
beginnen;
-- Diese Zeile wird erfolgreich sein, da sie nicht gesperrt ist (zuerst gesperrt und dann freigegeben).
Benutzer aktualisieren, Alter festlegen = 10, wobei Adresse = „Adresse2“;
-- Diese Zeile wird ebenfalls blockiert, da sie durch die Anweisung von trx1 gesperrt wurde. Alle Anweisungen, die die Bedingungen erfüllen, werden gesperrt. update user set age = 10 where address = „address3“;
--session1
begehen;
--session2
begehen;

-- Nicht eindeutiger Index + RR
--session1
Legen Sie die Isolationsstufe für Sitzungstransaktionen fest und erlauben Sie ein wiederholbares Lesen.
beginnen;
Löschen von Benutzer mit Alter = 20;
--session2
Legen Sie die Isolationsstufe für Sitzungstransaktionen fest und erlauben Sie ein wiederholbares Lesen.
beginnen;
-- Dies führt zu einer Blockierung, da der Datensatz mit Alter=20 in trx1 gesperrt wurde und eine GAP-Sperre hinzugefügt wurde, sodass 18 in das Sperrintervall gefallen ist. Einfügen in Benutzerwerte (E-Mail, Alter, Adresse) („[email protected]“, 18, „address4“);
--session1
begehen;
--session2
begehen;

-- Kein Index RR
--session1
Legen Sie die Isolationsstufe für Sitzungstransaktionen fest und erlauben Sie ein wiederholbares Lesen.
beginnen;
-- Wenn kein Index vorhanden ist, werden alle Datensätze in der Tabelle gesperrt und alle Lücken im Primärschlüsselindex werden gesperrt, um alle gleichzeitigen Aktualisierungsvorgänge zu verhindern. Löschen vom Benutzer, wobei Adresse = „Adresse3“ ist.
--session2
Legen Sie die Isolationsstufe für Sitzungstransaktionen fest und erlauben Sie ein wiederholbares Lesen.
beginnen;
-- Dies wird blockiert, da dem Primärschlüssel eine GAP-Sperre zugewiesen wurde. Daher kann das neue Einfügen nicht erfolgreich in die Benutzerwerte (E-Mail, Alter, Adresse) eingefügt werden („[email protected]“, 18, „address4“);
--session1
begehen;
--session2
begehen;

-- Einfaches Deadlock-Beispiel -- Sitzung1
beginnen;
Löschen vom Benutzer, bei dem ID = 1;
--session2
beginnen;
Löschen vom Benutzer mit ID = 3;
--session1
Löschen vom Benutzer, bei dem die ID = 3 ist;
--seession2
-- Hier stellt MySQL fest, dass ein Deadlock aufgetreten ist und unterbricht einen TRX
-- FEHLER 1213 (40001): Beim Versuch, eine Sperre zu erhalten, wurde ein Deadlock festgestellt. Versuchen Sie, die Transaktion neu zu starten.
Löschen vom Benutzer, bei dem ID = 1;
--session1
zurückrollen;
--Sitzung2;
zurückrollen;

- 5. Deadlock-Einfügung, Beispiel: Tabelle löschen, falls vorhanden, t1;
beginnen;
Tabelle t1 erstellen (
 `id` bigint ungleich null auto_increment,
 Primärschlüssel (`id`)
);
in t1-Werte einfügen (1);
in t1-Werte einfügen (5);
begehen;
wähle * aus t1;
--session1
beginnen;
in t1-Werte einfügen (2);
--sessionin2
beginnen;
-- Dadurch wird das Einfügen in t1-Werte blockiert (2).
--session3
beginnen;
-- Dadurch wird das Einfügen in t1-Werte blockiert (2).
--Sitzung1;
-- Zu diesem Zeitpunkt wird ein Rollback durchgeführt, trx2 und trx3 erhalten eine Benachrichtigung und MySQL unterbricht automatisch einen trx, da ein Deadlock auftritt -- FEHLER 1213 (40001): Beim Versuch, eine Sperre zu erhalten, wurde ein Deadlock festgestellt. Versuchen Sie, die Transaktion neu zu starten.
zurückrollen;
--Sitzung2;
zurückrollen;
--Sitzung3;
zurückrollen;

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. 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
  • Tutorial zur Beziehung zwischen Innodb-Transaktionsisolationsebene und Sperre in MySQL
  • Einführung in die Transaktionsisolationsebene von MySQL-Datenbanken (Transaction Isolation Level)
  • Kurze Analyse der MYSQL REPEATABLE-READ-Isolationsebene
  • Detaillierte Erklärung und Vergleich der vier Transaktionsisolationsebenen in MySQL
  • Detaillierte Analyse der MySQL-Transaktionsisolierung und ihrer Auswirkungen auf die Leistung
  • Detaillierte Erläuterung der vier Transaktionsisolationsebenen in MySQL

<<:  18 Tipps zur Konfiguration des Nginx-Proxy-Cache, die Betreiber kennen müssen (welche kennen Sie?)

>>:  Über das Wertübertragungsproblem zwischen Antd-Baum und übergeordneten und untergeordneten Komponenten (Reaktionszusammenfassung)

Artikel empfehlen

Einfache Anwendungsbeispiele für benutzerdefinierte MySQL-Funktionen

Dieser Artikel veranschaulicht anhand von Beispie...

So deinstallieren Sie IIS7-Web- und FTP-Dienste in Win7 vollständig

Nachdem ich gestern die PHP-Entwicklungsumgebung ...

Eine sehr detaillierte Erklärung der Linux C++ Multi-Thread-Synchronisierung

Inhaltsverzeichnis 1. Mutex 1. Initialisierung de...

Wie stelle ich Tomcat als automatisch gestarteten Dienst ein? Der schnellste Weg

Stellen Sie Tomcat so ein, dass der Dienst automa...

So verwenden Sie MySQL zur Abdeckung von Index- und Tabellenrückgabe

Zwei Hauptkategorien von Indizes Verwendete Speic...

Detaillierter Vergleich von Ember.js und Vue.js

Inhaltsverzeichnis Überblick Warum ein Framework ...

MySQL-Trigger: ausführliche Erklärung und einfaches Beispiel

Einfaches Beispiel für einen MySQL-Trigger Gramma...

JavaScript implementiert den Farbänderungseffekt durch Klicken mit neun Rastern

In diesem Artikel wird der spezifische JavaScript...

Wie man die Idee von Vue nutzt, um einen Speicher zu kapseln

Inhaltsverzeichnis Hintergrund Funktion Zweck Ide...