Dies ist ein populärwissenschaftlicher Artikel über Datenbankisolationsebenen. Ziel ist es, das berühmte Phantom-Read-Phänomen in Datenbanken zu verstehen. Um sich auf das Thema zu konzentrieren, werden Dirty Reads und nicht wiederholbare Lesevorgänge nicht behandelt. TransaktionsisolationsebeneMySQL verfügt über vier Transaktionsisolationsebenen:
Was ist Phantomlesen?Falsches Verständnis von Phantomlesen: Phantomlesen bedeutet, dass Transaktion A zwei Auswahlvorgänge ausführt, um unterschiedliche Datensätze zu erhalten, d. h. Auswahl 1 erhält 10 Datensätze und Auswahl 2 erhält 11 Datensätze. Dabei handelt es sich eigentlich nicht um einen Phantomlesevorgang, sondern um eine Art nicht wiederholbaren Lesevorgang, der nur auf der RU-RC-Ebene, nicht jedoch auf der MySQL-Standard-RR-Isolationsebene auftritt. Hier ist mein Verständnis von Phantomlesen: Phantom-Lesevorgänge bedeuten nicht, dass die aus mehreren Lesevorgängen in einer Transaktion erhaltenen Ergebnismengen unterschiedlich sind. Wichtiger bei Phantom-Lesevorgängen ist, dass der durch die aus einer bestimmten Auswahloperation erhaltene Ergebnismenge dargestellte Datenzustand nachfolgende Geschäftsoperationen nicht unterstützen kann. Genauer gesagt: Der ausgewählte Datensatz existiert nicht und Sie möchten diesen Datensatz einfügen. Wenn Sie jedoch den Befehl Einfügen ausführen, stellen Sie fest, dass dieser Datensatz bereits vorhanden ist und nicht eingefügt werden kann, genau wie eine Illusion Ein Beispiel mag das Verständnis erleichtern: mysql> zeigen erstellen Tabelle user\G *************************** 1. Reihe *************************** Tabelle: Benutzer Tabelle erstellen: CREATE TABLE `user` ( `id` int(11) NICHT NULL, `name` varchar(32) DEFAULT NULL, PRIMÄRSCHLÜSSEL (`id`) ) ENGINE=InnoDB STANDARD-CHARSET=utf8 Starten Sie zwei Transaktionen T1 und T2 und stellen Sie ihre Isolationsebenen auf Reaptable-Read ein: T1: mysql> globale Transaktionsisolationsebene für wiederholbares Lesen festlegen; mysql> beginnen; mysql> wähle * vom Benutzer aus; mysql> in Benutzerwerte einfügen (1, 'Jeff'); FEHLER 1062 (23000): Doppelter Eintrag „1“ für Schlüssel „PRIMARY“ mysql> wähle * vom Benutzer aus; T2: mysql> globale Transaktionsisolationsebene für wiederholbares Lesen festlegen; mysql> beginnen; mysql> in Benutzerwerte einfügen (1, 'Jeff'); mysql> festschreiben; Die T1-Transaktion prüft, ob in der Tabelle ein Datensatz mit der ID 1 vorhanden ist, und fügt ihn ein, wenn nicht. T2 fügt Interferenzdatensätze ein, die Phantomlesevorgänge in T1 verursachen. Im obigen Beispiel muss sichergestellt werden, dass die Ausführung der Transaktion T1 vor der Ausführung der Transaktion T2 beginnt. Im obigen Beispiel tritt bei T1 ein Phantomlesen auf, da der von T1 gelesene Datenzustand einen semantischen Konflikt mit den nachfolgenden Aktionen aufweist: Bei der Abfrage wird eindeutig darauf hingewiesen, dass der Datensatz nicht vorhanden ist, beim Einfügen jedoch darauf hingewiesen, dass der Primärschlüssel wiederholt wird, was dem Auftreten eines Phantoms ähnelt und daher als Phantomlesen bezeichnet wird. So vermeiden Sie Phantom-ReadsMySQL bietet derzeit zwei Möglichkeiten, Phantom-Lesevorgänge zu verhindern: 1. Fügen Sie der Auswahloperation manuell eine Zeile-X-Sperre hinzu (SELECT ... FOR UPDATE). Der Grund dafür ist, dass die Zeilensperre in InnoDB den Index sperrt. Selbst wenn der aktuelle Datensatz nicht existiert, erhält die aktuelle Transaktion eine Datensatzsperre (wenn der Datensatz existiert, wird eine Zeilen-X-Sperre hinzugefügt, wenn er nicht existiert, wird eine Lücken-X-Sperre für die nächste Schlüsselsperre hinzugefügt). Auf diese Weise können andere Transaktionen keine Datensätze dieses Index einfügen, wodurch Phantom-Lesevorgänge vermieden werden. mysql> beginnen; mysql> wähle * vom Benutzer, wobei ID = 2 für Update; mysql> in Benutzerwerte einfügen (2, 'Tony'); mysql> festschreiben; T2: mysql> beginnen; mysql> in Benutzerwerte einfügen (2, 'Jimmy'); FEHLER 1062 (23000): Doppelter Eintrag „2“ für Schlüssel „PRIMARY“ Wenn T1 nun mit „Update“ abgefragt wird, wird der Index in Innodb gesperrt (auch wenn er derzeit nicht existiert), sodass das Einfügen der Transaktion T2 blockiert wird, bis T1 festgeschrieben ist. Auf diese Weise ist T1 erfolgreich. Für T1 wird das Phantomlesen tatsächlich eliminiert, aber das Einfügen von T2 wird einen doppelten Primärschlüssel melden, was ebenfalls den Erwartungen entspricht. Wer interessiert ist, kann eine andere Möglichkeit ausprobieren, die Isolationsstufe zu verbessern und Phantom-Lesevorgänge zu eliminieren. Ich werde es hier nicht wiederholen. Das Prinzip ist ähnlich, außer dass das System die manuelle Sperrung ersetzt. ZusammenfassenRR ist die Standardisolationsebene von MySQL-Transaktionen. Sie stellt einen Kompromiss zwischen Transaktionssicherheit und Leistung dar. Wenn Entwickler Phantom-Lesevorgänge richtig verstehen, können sie je nach Bedarf entscheiden, ob sie Phantom-Lesevorgänge verhindern möchten. SERIALIZABLE ist pessimistisch und geht davon aus, dass Phantom-Lesevorgänge immer stattfinden werden. Daher fügt es automatisch und implizit exklusive Sperren für die von der Transaktion benötigten Ressourcen hinzu. Andere Transaktionen, die auf diese Ressource zugreifen, werden blockiert und warten. Die Transaktion ist sicher, aber die Leistung muss sorgfältig berücksichtigt werden. InnoDB-Sperren dienen der Beachtung der Indizes. Sperren Sie den Zeilendatensatz. Wenn er vorhanden ist, fügen Sie eine X-Sperre hinzu. Andernfalls fügen Sie eine Next-Key-Sperre / Lückensperre / Lückensperre hinzu. Daher kann InnoDB die Vorbelegung eines bestimmten Datensatzes durch eine Transaktion realisieren. Solange die Transaktion noch vorhanden ist, können andere Transaktionen sie nicht belegen. Zu Sperren folgt später noch ein gesonderter Artikel. Oben finden Sie eine ausführliche Erklärung zu MySQL-Phantomlesevorgängen und wie man sie beseitigt. Weitere Informationen zu MySQL-Phantomlesevorgängen und wie man sie beseitigt, finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erklärung des TARGET-Attributs des HTML-Hyperlink-Tags A
>>: So legen Sie die Speichergröße von Docker Tomcat fest
Kürzlich haben Studierende des User Experience-Tea...
Frage Nach dem Nginx-Reverse-Proxy erhält die Tom...
Konfigurationsbeispiel Upstream-Backend { Server ...
Sortierproblem Ich habe kürzlich auf Geek Time „4...
Ich habe VMware und Ubuntu neu installiert, aber ...
Einführung in Struktur und Leistung HTML-Struktur...
In diesem Artikel wird der spezifische Code zur V...
Heutige Webdesigns neigen dazu, sehr große Schrif...
Die dekomprimierte Version von MySQL ist installi...
Holen Sie sich das Mongo-Image sudo docker pull m...
Inhaltsverzeichnis Erstellen Sie eine neue HTML-D...
Gefühle: Ich bin Backend-Entwickler. Manchmal fühl...
Oftmals erwarten wir, dass das Abfrageergebnis hö...
Die Volltextindizierung erfordert eine spezielle ...
mycli MyCLI ist eine Befehlszeilenschnittstelle f...