Ich denke, die oben genannten Isolationsstufen sind so ähnlich. Könnte jemand bitte mit ein paar schönen Beispielen beschreiben, was der Hauptunterschied ist?
Ich denke, die oben genannten Isolationsstufen sind so ähnlich. Könnte jemand bitte mit ein paar schönen Beispielen beschreiben, was der Hauptunterschied ist?
Antworten:
Read Commit ist eine Isolationsstufe, die garantiert, dass alle zum Zeitpunkt des Lesens festgeschriebenen gelesenen Daten gelesen werden. Es hindert den Leser lediglich daran, zwischenzeitliche, nicht festgeschriebene, "schmutzige" Lesevorgänge zu sehen. Es wird keinerlei Zusage gemacht, dass Daten nach dem Lesen geändert werden können, wenn die Transaktion den Lesevorgang erneut ausgibt und dieselben Daten findet.
Wiederholbares Lesen ist eine höhere Isolationsstufe, die zusätzlich zu den Garantien der Lese-Festschreibungsstufe auch garantiert, dass sich das Lesen von Daten nicht ändern kann. Wenn die Transaktion dieselben Daten erneut liest, werden die zuvor gelesenen Daten unverändert an Ort und Stelle gefunden und zum Lesen verfügbar.
Die nächste Isolationsstufe, serialisierbar, bietet eine noch stärkere Garantie: Zusätzlich zu allen wiederholbaren Lesegarantien wird auch garantiert, dass bei einem nachfolgenden Lesevorgang keine neuen Daten sichtbar werden.
Angenommen, Sie haben eine Tabelle T mit einer Spalte C mit einer Zeile darin. Angenommen, sie hat den Wert '1'. Und denken Sie daran, dass Sie eine einfache Aufgabe wie die folgende haben:
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;
Dies ist eine einfache Aufgabe, bei der zwei Lesevorgänge aus Tabelle T mit einer Verzögerung von 1 Minute ausgeführt werden.
Wenn Sie der obigen Logik folgen, können Sie schnell erkennen, dass SERIALIZABLE-Transaktionen, obwohl sie Ihnen das Leben erleichtern, jede mögliche gleichzeitige Operation immer vollständig blockieren , da sie erfordern, dass niemand eine Zeile ändern, löschen oder einfügen kann. Die Standard-Transaktionsisolationsstufe des .Net- System.Transactions
Bereichs ist serialisierbar. Dies erklärt normalerweise die daraus resultierende miserable Leistung.
Und schließlich gibt es noch die SNAPSHOT-Isolationsstufe. Die SNAPSHOT-Isolationsstufe bietet die gleichen Garantien wie die Serialisierbarkeit, erfordert jedoch nicht, dass keine gleichzeitige Transaktion die Daten ändern kann. Stattdessen zwingt es jeden Leser, seine eigene Version der Welt zu sehen (es ist ein eigener "Schnappschuss"). Dies macht es sehr einfach zu programmieren und sehr skalierbar, da es keine gleichzeitigen Updates blockiert. Dieser Vorteil ist jedoch mit einem Preis verbunden: zusätzlicher Verbrauch an Serverressourcen.
Ergänzende Lesungen:
Der Status der Datenbank wird ab dem Start der Transaktion beibehalten. Wenn Sie einen Wert in Sitzung1 abrufen, aktualisieren Sie diesen Wert in Sitzung2. Wenn Sie ihn in Sitzung1 erneut abrufen, werden dieselben Ergebnisse zurückgegeben. Lesevorgänge sind wiederholbar.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
Im Kontext einer Transaktion rufen Sie immer den zuletzt festgeschriebenen Wert ab. Wenn Sie einen Wert in Sitzung1 abrufen, ihn in Sitzung2 aktualisieren und dann wieder in Sitzung1 abrufen, erhalten Sie den in Sitzung2 geänderten Wert. Es liest die letzte festgeschriebene Zeile.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Bob
Macht Sinn?
Einfach die Antwort nach meinem Lesen und Verstehen auf diesen Thread und die Antwort von @ remus-rusanu basiert auf diesem einfachen Szenario:
Es gibt zwei Prozesse A und B. Prozess B liest Tabelle X Prozess A schreibt in Tabelle X Prozess B liest erneut Tabelle X.
Alte Frage, die bereits eine akzeptierte Antwort hat, aber ich denke gerne an diese beiden Isolationsstufen, wie sie das Sperrverhalten in SQL Server ändern. Dies könnte für diejenigen hilfreich sein, die Deadlocks wie ich debuggen.
READ COMMITTED (Standard)
Freigegebene Sperren werden in SELECT übernommen und dann freigegeben, wenn die SELECT-Anweisung abgeschlossen ist . Auf diese Weise kann das System sicherstellen, dass nicht festgeschriebene Daten nicht fehlerhaft gelesen werden. Andere Transaktionen können die zugrunde liegenden Zeilen nach Abschluss von SELECT und vor Abschluss Ihrer Transaktion noch ändern.
WIEDERHOLBAR LESEN
Freigegebene Sperren werden in SELECT übernommen und erst nach Abschluss der Transaktion freigegeben . Auf diese Weise kann das System sicherstellen, dass sich die von Ihnen gelesenen Werte während der Transaktion nicht ändern (da sie bis zum Abschluss der Transaktion gesperrt bleiben).
Der Versuch, diesen Zweifel mit einfachen Diagrammen zu erklären.
Festgeschrieben lesen: Hier in dieser Isolationsstufe liest Transaktion T1 den aktualisierten Wert des von Transaktion T2 festgeschriebenen X.
Wiederholbares Lesen: In dieser Isolationsstufe berücksichtigt die Transaktion T1 nicht die von der Transaktion T2 festgeschriebenen Änderungen.
Ich denke, dieses Bild kann auch nützlich sein, es hilft mir als Referenz, wenn ich mich schnell an die Unterschiede zwischen den Isolationsstufen erinnern möchte (dank kudvenkat auf youtube)
Bitte beachten Sie, dass sich das Wiederholbare in Wiederholbarem auf ein Tupel bezieht, jedoch nicht auf die gesamte Tabelle. In ANSC-Isolationsstufen kann es zu einer Phantom- Leseanomalie kommen. Dies bedeutet, dass eine Tabelle mit derselben where-Klausel zweimal unterschiedliche Rückgabewerte und unterschiedliche Ergebnismengen zurückgeben kann. Es ist buchstäblich nicht wiederholbar .
Meine Beobachtung zur ursprünglich akzeptierten Lösung.
Unter RR (Standard-MySQL) - Wenn ein TX geöffnet ist und ein SELECT ausgelöst wurde, kann ein anderer TX KEINE Zeile löschen, die zur vorherigen READ-Ergebnismenge gehört, bis der vorherige TX festgeschrieben wurde (tatsächlich bleibt die Löschanweisung im neuen TX einfach hängen). Der nächste TX kann jedoch problemlos alle Zeilen aus der Tabelle löschen . Übrigens werden beim nächsten LESEN im vorherigen Text die alten Daten weiterhin angezeigt, bis sie festgeschrieben werden.