Database
 sql >> Datenbank >  >> RDS >> Database

Die Read Uncommitted-Isolationsstufe

[Siehe den Index für die gesamte Serie]

Read uncommitted ist die schwächste der vier im SQL-Standard definierten Transaktionsisolationsstufen (und der sechs in SQL Server implementierten). Es erlaubt alle drei sogenannten "Parallelitätsphänomene", Dirty Reads , nicht wiederholbare Lesevorgänge , und Phantome:

Die meisten Datenbankmitarbeiter sind sich dieser Phänomene zumindest in Umrissen bewusst, aber nicht jeder erkennt, dass sie die angebotenen Isolationsgarantien nicht vollständig beschreiben; Sie beschreiben auch nicht intuitiv die unterschiedlichen Verhaltensweisen, die man in einer bestimmten Implementierung wie SQL Server erwarten kann. Dazu später mehr.

Transaktionsisolation – das „I“ in ACID

Jeder SQL-Befehl wird innerhalb einer Transaktion ausgeführt (explizit, implizit oder automatisch festgeschrieben). Jede Transaktion hat eine zugeordnete Isolationsstufe, die bestimmt, wie isoliert sie von den Auswirkungen anderer gleichzeitiger Transaktionen ist. Dieses etwas technische Konzept hat wichtige Auswirkungen auf die Art und Weise, wie Abfragen ausgeführt werden, und auf die Qualität der Ergebnisse, die sie produzieren.

Stellen Sie sich eine einfache Abfrage vor, die alle Zeilen in einer Tabelle zählt. Wenn diese Abfrage sofort ausgeführt werden könnte (oder ohne gleichzeitige Datenänderungen), könnte es nur eine richtige Antwort geben:die Anzahl der Zeilen, die zu diesem Zeitpunkt physisch in der Tabelle vorhanden sind. In Wirklichkeit dauert die Ausführung der Abfrage eine gewisse Zeit, und das Ergebnis hängt davon ab, auf wie viele Zeilen die Ausführungsmaschine tatsächlich stößt, wenn sie die für den Zugriff auf die Daten gewählte physische Struktur durchläuft.

Wenn Zeilen durch gleichzeitige Transaktionen zur Tabelle hinzugefügt (oder daraus gelöscht) werden, während der Zählvorgang ausgeführt wird, können unterschiedliche Ergebnisse erzielt werden, je nachdem, ob die Zeilenzählungstransaktion auf alle, einige oder keine dieser gleichzeitigen Änderungen stößt – welche hängt wiederum von der Isolationsstufe der Zeilenzählungstransaktion ab.

Abhängig von der Isolationsstufe, den physischen Details und dem Timing der gleichzeitigen Vorgänge könnte unsere Zähltransaktion sogar ein Ergebnis liefern, das zu keinem Zeitpunkt während der Transaktion eine echte Widerspiegelung des festgeschriebenen Zustands der Tabelle war.

Beispiel

Stellen Sie sich eine Zeilenzählungstransaktion vor, die zum Zeitpunkt T1 beginnt und die Tabelle von Anfang bis Ende durchsucht (der Argumentation halber in der Reihenfolge der Clustered-Index-Schlüssel). In diesem Moment gibt es 100 festgeschriebene Zeilen in der Tabelle. Einige Zeit später (zum Zeitpunkt T2) ist unsere Zähltransaktion auf 50 dieser Zeilen gestoßen. Im selben Moment fügt eine gleichzeitige Transaktion zwei Zeilen in die Tabelle ein und schreibt kurze Zeit später zum Zeitpunkt T3 (bevor die Zähltransaktion endet). Eine der eingefügten Zeilen fällt zufällig in die Hälfte der Clustered-Index-Struktur, die unsere Zähltransaktion bereits verarbeitet hat, während die andere eingefügte Zeile im nicht gezählten Teil liegt.

Wenn die Zeilenzählungstransaktion abgeschlossen ist, werden in diesem Szenario 101 Zeilen gemeldet; 100 anfängliche Zeilen in der Tabelle plus die einzelne eingefügte Zeile, die während des Scans gefunden wurde. Dieses Ergebnis steht im Widerspruch zum festgeschriebenen Verlauf der Tabelle:Es gab 100 festgeschriebene Zeilen zu den Zeiten T1 und T2, dann 102 festgeschriebene Zeilen zum Zeitpunkt T3. Es gab noch nie eine Zeit, in der es 101 festgeschriebene Zeilen gab.

Das Überraschende (vielleicht abhängig davon, wie gründlich Sie zuvor über diese Dinge nachgedacht haben) ist, dass dieses Ergebnis auf der standardmäßigen (sperrenden) Read Committed-Isolationsebene und sogar unter wiederholbarer Leseisolation möglich ist. Beide Isolationsstufen lesen garantiert nur festgeschriebene Daten, aber wir haben ein Ergebnis erhalten, das keinen festgeschriebenen Zustand der Datenbank darstellt!

Analyse

Die einzige Transaktionsisolationsebene, die eine vollständige Isolation von Nebenläufigkeitseffekten bietet, ist serialisierbar. Die SQL Server-Implementierung der serialisierbaren Isolationsstufe bedeutet, dass eine Transaktion die zuletzt festgeschriebenen Daten ab dem Zeitpunkt sieht, an dem die Daten zum ersten Mal für den Zugriff gesperrt wurden. Darüber hinaus wird garantiert, dass der Datensatz, der unter der serialisierbaren Isolation angetroffen wird, seine Mitgliedschaft nicht ändert, bevor die Transaktion endet.

Das Beispiel der Zeilenzählung hebt einen grundlegenden Aspekt der Datenbanktheorie hervor:Wir müssen uns darüber im Klaren sein, was ein „korrektes“ Ergebnis für eine Datenbank bedeutet, die gleichzeitig Änderungen erfährt, und wir müssen die Kompromisse verstehen, die wir eingehen, wenn wir eine Isolierung auswählen Ebene niedriger als serialisierbar.

Wenn wir eine Point-in-Time-Ansicht des festgeschriebenen Zustands der Datenbank benötigen, sollten wir die Snapshot-Isolation (für Garantien auf Transaktionsebene) oder die Read-Committed-Snapshot-Isolation (für Garantien auf Anweisungsebene) verwenden. Beachten Sie jedoch, dass eine Point-in-Time-Ansicht bedeutet, dass wir nicht unbedingt mit dem aktuellen festgeschriebenen Zustand der Datenbank arbeiten; Tatsächlich verwenden wir möglicherweise veraltete Informationen. Wenn wir andererseits mit Ergebnissen zufrieden sind, die nur auf festgeschriebenen Daten basieren (wenn auch möglicherweise von unterschiedlichen Zeitpunkten), könnten wir uns dafür entscheiden, bei der standardmäßigen Isolationsstufe zum Sperren von festgeschriebenen Lesevorgängen zu bleiben.

Um sicher zu sein, Ergebnisse zu erzielen (und Entscheidungen zu treffen!), die auf dem neuesten Satz festgeschriebener Daten basieren, benötigen wir für einen gewissen seriellen Verlauf von Operationen gegen die Datenbank eine serialisierbare Transaktionsisolation. Natürlich ist diese Option im Hinblick auf den Ressourcenverbrauch und die geringere Parallelität (einschließlich eines erhöhten Deadlock-Risikos) in der Regel am teuersten.

Im Beispiel der Zeilenzählung würden beide Snapshot-Isolationsstufen (SI und RCSI) ein Ergebnis von 100 Zeilen liefern, was die Anzahl der festgeschriebenen Zeilen zu Beginn der Anweisung (und in diesem Fall der Transaktion) darstellt. Das Ausführen der Abfrage bei Locking Read Committed oder Repeatable Read Isolation könnte zu einem Ergebnis von 100, 101 oder 102 Zeilen führen – je nach Timing, Lock-Granularität, Zeileneinfügeposition und der gewählten physischen Zugriffsmethode. Bei der serialisierbaren Isolierung wäre das Ergebnis entweder 100 oder 102 Zeilen, je nachdem, welche der beiden gleichzeitigen Transaktionen als zuerst ausgeführt gilt.

Wie schlimm ist das Lesen ohne Committed?

Nachdem Sie die Read Uncommitted-Isolation als schwächste der verfügbaren Isolationsstufen eingeführt haben, sollten Sie davon ausgehen, dass sie noch geringere Isolationsgarantien bietet als das Sperren von Read Committed (die nächsthöhere Isolationsstufe). In der Tat tut es das; Die Frage ist jedoch:Wie viel schlimmer ist es, als die Read-Committed-Isolation zu sperren?

Damit wir mit dem richtigen Kontext beginnen, finden Sie hier eine Liste der wichtigsten Nebenläufigkeitseffekte, die unter der standardmäßigen SQL Server-Sperr-Isolationsstufe mit festgeschriebenem Lesezugriff auftreten können:

  • Fehlende festgeschriebene Zeilen
  • Zeilen mehrfach aufgetreten
  • Verschiedene Versionen derselben Zeile, die in einem einzigen Anweisungs-/Abfrageplan angetroffen werden
  • Festgeschriebene Spaltendaten von verschiedenen Zeitpunkten in derselben Zeile (Beispiel)

Diese Nebenläufigkeitseffekte sind alle darauf zurückzuführen, dass die Sperrimplementierung von Read Committed nur sehr kurzfristige gemeinsame Sperren beim Lesen von Daten verwendet. Die Read-Uncommitted-Isolationsstufe geht noch einen Schritt weiter, indem überhaupt keine Shared-Locks genommen werden, was zu der zusätzlichen Möglichkeit von "Dirty Reads" führt.

Dirty Reads

Zur Erinnerung:„Dirty Read“ bezieht sich auf das Lesen von Daten, die durch eine andere gleichzeitige Transaktion geändert werden (wobei „Ändern“ Einfüge-, Aktualisierungs-, Lösch- und Zusammenführungsvorgänge umfasst). Anders ausgedrückt, ein Dirty Read tritt auf, wenn eine Transaktion Daten liest, die eine andere Transaktion geändert hat, bevor die ändernde Transaktion diese Änderungen festgeschrieben oder abgebrochen hat.

Vor- und Nachteile

Die Hauptvorteile der Lese-Uncommitted-Isolation sind das verringerte Potenzial für Blockierungen und Deadlocks aufgrund inkompatibler Sperren (einschließlich unnötiger Blockierungen aufgrund von Sperreneskalation) und möglicherweise eine erhöhte Leistung (durch Vermeidung der Notwendigkeit, gemeinsam genutzte Sperren zu erwerben und freizugeben).

Der offensichtlichste potenzielle Nachteil der Read Uncommitted-Isolation ist (wie der Name schon sagt), dass wir möglicherweise nicht festgeschriebene Daten lesen (sogar Daten, die nie sind festgeschrieben, im Falle eines Transaktions-Rollbacks). In einer Datenbank, in der Rollbacks relativ selten sind, könnte die Frage des Lesens nicht festgeschriebener Daten als reines Zeitproblem angesehen werden, da die fraglichen Daten sicherlich irgendwann und wahrscheinlich ziemlich bald festgeschrieben werden. Wir haben bereits zeitbezogene Inkonsistenzen im Zeilenzählungsbeispiel gesehen (das auf einer höheren Isolationsstufe betrieben wurde), sodass man sich durchaus fragen könnte, wie wichtig es ist, Daten „zu früh“ zu lesen.

Natürlich hängt die Antwort von den lokalen Prioritäten und dem Kontext ab, aber eine fundierte Entscheidung für die Verwendung von Read Uncommitted Isolation scheint sicherlich möglich zu sein. Es gibt jedoch mehr zu bedenken. Die SQL Server-Implementierung der Read Uncommitted-Isolationsstufe enthält einige subtile Verhaltensweisen, die wir kennen müssen, bevor wir diese „informierte Entscheidung“ treffen.

Scans der Zuordnungsreihenfolge

Die Verwendung der Read Uncommitted-Isolation wird von SQL Server als Signal dafür gewertet, dass wir bereit sind, die Inkonsistenzen zu akzeptieren, die als Ergebnis eines Scans mit Zuordnungsreihenfolge auftreten können.

Normalerweise kann die Speicher-Engine nur einen nach Zuordnung geordneten Scan auswählen, wenn die zugrunde liegenden Daten garantiert nicht geändert werden während des Scans (z. B. weil die Datenbank schreibgeschützt ist oder ein Tabellensperrhinweis angegeben wurde). Wenn jedoch die Lese-Uncommitted-Isolation verwendet wird, kann die Speicher-Engine immer noch einen nach Zuordnung geordneten Scan auswählen, selbst wenn die zugrunde liegenden Daten durch gleichzeitige Transaktionen geändert werden könnten.

Unter diesen Umständen kann der zuweisungsgeordnete Scan einige festgeschriebene Daten vollständig verfehlen oder mehr als einmal auf andere festgeschriebene Daten stoßen. Die Betonung liegt dort auf fehlender oder doppelter Zählung begangen data (kein Lesen von nicht festgeschriebenen Daten), so dass es sich nicht um "Dirty Reads" als solches handelt. Diese Entwurfsentscheidung (Zuweisungsgeordnete Scans unter Read-Uncommitted-Isolation zuzulassen) wird von einigen Leuten als ziemlich kontrovers angesehen.

Als Einschränkung sollte klar sein, dass das allgemeinere Risiko, dass festgeschriebene Zeilen fehlen oder doppelt gezählt werden, nicht auf das Lesen von nicht festgeschriebener Isolation beschränkt ist. Es ist sicherlich möglich, ähnliche Effekte beim Sperren von festgeschriebenen und wiederholbaren Lesevorgängen zu sehen (wie wir zuvor gesehen haben), aber dies geschieht über einen anderen Mechanismus. Festgeschriebene Zeilen fehlen oder werden mehrmals aufgrund eines zuweisungsgeordneten Scans über sich ändernde Daten angezeigt ist spezifisch für die Verwendung von Read Uncommitted Isolation.

Lesen "beschädigter" Daten

Ergebnisse, die sich der Logik zu widersetzen scheinen (und sogar Constraints prüfen!), sind unter Locking-Read-Committed-Isolation möglich (wiederum finden Sie einige Beispiele in diesem Artikel von Craig Freedman). Zusammenfassend lässt sich sagen, dass das Sperren von festgeschriebenen Lesevorgängen festgeschriebene Daten von verschiedenen Zeitpunkten sehen kann – sogar für eine einzelne Zeile, wenn der Abfrageplan beispielsweise Techniken wie die Indexüberschneidung verwendet.

Diese Ergebnisse können unerwartet sein, aber sie entsprechen vollständig der Garantie, nur festgeschriebene Daten zu lesen. Es führt einfach kein Weg daran vorbei, dass höhere Datenkonsistenzgarantien höhere Isolationsstufen erfordern.

Diese Beispiele können sogar ziemlich schockierend sein, wenn Sie sie noch nie zuvor gesehen haben. Die gleichen Ergebnisse sind natürlich bei der Read-Uncommitted-Isolation möglich, aber das Zulassen von Dirty Reads fügt eine zusätzliche Dimension hinzu:Die Ergebnisse können festgeschriebene und nicht festgeschriebene Daten von unterschiedlichen Zeitpunkten enthalten, sogar für dieselbe Zeile.

Darüber hinaus ist es sogar möglich, dass eine nicht festgeschriebene Lesetransaktion einen einzelnen Spaltenwert liest in einem gemischten Zustand von festgeschriebenen und nicht festgeschriebenen Daten. Dies kann beim Lesen eines LOB-Werts (z. B. xml oder einer der „max“-Typen) auftreten, wenn der Wert auf mehreren Datenseiten gespeichert ist. Ein nicht festgeschriebener Lesevorgang kann festgeschriebene oder nicht festgeschriebene Daten von verschiedenen Zeitpunkten auf verschiedenen Seiten finden, was zu einem endgültigen einspaltigen Wert führt, der eine Mischung von Werten ist!

Betrachten Sie als Beispiel eine einzelne varchar(max)-Spalte, die anfänglich 10.000 „x“-Zeichen enthält. Eine gleichzeitige Transaktion aktualisiert diesen Wert auf 10.000 'y'-Zeichen. Eine nicht festgeschriebene Lesetransaktion kann 'x' Zeichen von einer Seite des LOB und 'y' Zeichen von einer anderen Seite lesen, was zu einem endgültigen Lesewert führt, der eine Mischung aus 'x' und 'y' Zeichen enthält. Es ist schwer zu argumentieren, dass dies nicht das Lesen "korrupter" Daten darstellt.

Demo

Erstellen Sie eine gruppierte Tabelle mit einer einzelnen Zeile von LOB-Daten:

CREATE TABLE dbo.Test
(
    RowID integer PRIMARY KEY,
    LOB varchar(max) NOT NULL,
);
 
INSERT dbo.Test
    (RowID, LOB)
VALUES
    (1, REPLICATE(CONVERT(varchar(max), 'X'), 16100));

Führen Sie in einer separaten Sitzung das folgende Skript aus, um den LOB-Wert beim Lesen ohne Commit zu lesen:

-- Run this in session 2
SET NOCOUNT ON;
 
DECLARE 
    @ValueRead varchar(max) = '',
    @AllXs varchar(max) = REPLICATE(CONVERT(varchar(max), 'X'), 16100),
    @AllYs varchar(max) = REPLICATE(CONVERT(varchar(max), 'Y'), 16100);
 
WHILE 1 = 1
BEGIN
    SELECT @ValueRead = T.LOB
    FROM dbo.Test AS T WITH (READUNCOMMITTED)
    WHERE T.RowID = 1;
 
    IF @ValueRead NOT IN (@AllXs, @AllYs)
    BEGIN
    	PRINT LEFT(@ValueRead, 8000);
        PRINT RIGHT(@ValueRead, 8000);
        BREAK;
    END
END;

Führen Sie in der ersten Sitzung dieses Skript aus, um abwechselnde Werte in die LOB-Spalte zu schreiben:

-- Run this in session 1
SET NOCOUNT ON;
 
DECLARE 
    @AllXs varchar(max) = REPLICATE(CONVERT(varchar(max), 'X'), 16100),
    @AllYs varchar(max) = REPLICATE(CONVERT(varchar(max), 'Y'), 16100);
 
WHILE 1 = 1
BEGIN
    UPDATE dbo.Test
    SET LOB = @AllYs
    WHERE RowID = 1;
 
    UPDATE dbo.Test
    SET LOB = @AllXs
    WHERE RowID = 1;
END;

Nach kurzer Zeit wird das Skript in Sitzung zwei beendet, nachdem es einen gemischten Zustand für den LOB-Wert gelesen hat, zum Beispiel:

Dieses spezielle Problem beschränkt sich auf Lesevorgänge von LOB-Spaltenwerten, die über mehrere Seiten verteilt sind, nicht aufgrund von Garantien der Isolationsstufe, sondern weil SQL Server Latches auf Seitenebene verwendet, um die physische Integrität sicherzustellen. Ein Nebeneffekt dieses Implementierungsdetails ist, dass es solche "beschädigten" Datenlesevorgänge verhindert, wenn sich die Daten für einen einzelnen Lesevorgang zufällig auf einer einzelnen Seite befinden.

Abhängig von Ihrer Version von SQL Server erhalten Sie beim Lesen von „Mixed State“-Daten für eine XML-Spalte entweder einen Fehler, der sich aus dem möglicherweise fehlerhaften XML-Ergebnis ergibt, überhaupt keinen Fehler oder den nicht festgeschriebenen spezifischen Fehler 601 , "konnte den Scan mit NOLOCK aufgrund einer Datenverschiebung nicht fortsetzen." Das Lesen von Mixed-State-Daten für andere LOB-Typen führt im Allgemeinen nicht zu einer Fehlermeldung; Die verbrauchende Anwendung oder Abfrage kann nicht wissen, dass sie gerade die schlimmste Art von Dirty Read erfahren hat. Um die Analyse abzuschließen, wird eine Nicht-LOB-Zeile mit gemischtem Zustand, die als Ergebnis einer Indexüberschneidung gelesen wird, niemals als Fehler gemeldet.

Die Botschaft hier ist, dass Sie, wenn Sie Read Uncommitted Isolation verwenden, akzeptieren, dass Dirty Reads die Möglichkeit beinhalten, "beschädigte" LOB-Werte mit gemischtem Zustand zu lesen.

Der NOLOCK-Hinweis

Ich nehme an, keine Diskussion über die Read Uncommitted-Isolationsstufe wäre vollständig, ohne zumindest diesen (weitgehend überstrapazierten und missverstandenen) Tabellenhinweis zu erwähnen. Der Hinweis selbst ist nur ein Synonym für den READUNCOMMITTED-Tabellenhinweis. Es führt genau die gleiche Funktion aus:Auf das Objekt, auf das es angewendet wird, wird unter Verwendung der Read-Uncommitted-Isolationssemantik zugegriffen (obwohl es eine Ausnahme gibt).

Was den Namen "NOLOCK" betrifft, bedeutet dies einfach, dass beim Lesen von Daten keine gemeinsamen Sperren verwendet werden . Andere Sperren (Schemastabilität, exklusive Sperren für Datenänderungen usw.) werden weiterhin wie gewohnt verwendet.

Im Allgemeinen sollten NOLOCK-Hinweise ungefähr so ​​häufig vorkommen wie andere objektbezogene Isolationsstufen-Tabellenhinweise wie SERIALIZABLE und READCOMMITTEDLOCK. Das heißt:überhaupt nicht sehr verbreitet und nur dort verwendet, wo es keine gute Alternative, einen klar definierten Zweck und eine vollständige gibt Verständnis der Konsequenzen.

Ein Beispiel für eine legitime Verwendung von NOLOCK (oder READUNCOMMITTED) ist der Zugriff auf DMVs oder andere Systemansichten, bei denen eine höhere Isolationsstufe zu unerwünschten Konflikten bei Nicht-Benutzerdatenstrukturen führen kann. Ein weiteres Grenzfallbeispiel könnte sein, wenn eine Abfrage auf einen erheblichen Teil einer großen Tabelle zugreifen muss, die garantiert niemals Datenänderungen erfährt, während die angedeutete Abfrage ausgeführt wird. Es müsste einen guten Grund geben, stattdessen keine Snapshot- oder Read-Committed-Snapshot-Isolation zu verwenden, und die erwarteten Leistungssteigerungen müssten getestet, validiert und beispielsweise mit der Verwendung eines einzelnen gemeinsam genutzten Tabellensperrhinweises verglichen werden.

Die am wenigsten wünschenswerte Verwendung von NOLOCK ist die, die leider am häufigsten vorkommt:die Anwendung auf jedes Objekt in einer Abfrage als eine Art magischer Schalter, um schneller zu werden. Beim besten Willen der Welt gibt es einfach keine bessere Möglichkeit, SQL Server-Code entschieden dilettantisch aussehen zu lassen. Wenn Sie für eine Abfrage, einen Codeblock oder ein Modul berechtigterweise eine Read Uncommitted-Isolation benötigen, ist es wahrscheinlich besser, die Sitzungsisolationsstufe entsprechend festzulegen und Kommentare anzugeben, um die Aktion zu rechtfertigen.

Abschließende Gedanken

Read uncommitted ist eine legitime Wahl für die Transaktionsisolationsstufe, aber es muss eine fundierte Wahl sein. Zur Erinnerung:Hier sind einige der Nebenläufigkeitsphänomene, die unter der standardmäßigen SQL Server-Sperr-Isolation mit festgeschriebenem Lesezugriff möglich sind:

  • Fehlende zuvor festgeschriebene Zeilen
  • Committed-Zeilen mehrfach aufgetreten
  • Verschiedene festgeschriebene Versionen derselben Zeile, die in einem einzigen Anweisungs-/Abfrageplan angetroffen werden
  • Festgeschriebene Daten von verschiedenen Zeitpunkten in derselben Zeile (aber verschiedenen Spalten)
  • Festgeschriebene Datenlesevorgänge, die aktivierten und aktivierten Einschränkungen zu widersprechen scheinen

Je nach Ihrem Standpunkt könnte das eine ziemlich schockierende Liste möglicher Inkonsistenzen für die Standardisolationsstufe sein. Zu dieser Liste fügt Read Uncommitted Isolation hinzu:

  • Dirty Reads (Auffinden von Daten, die noch nicht festgeschrieben wurden und möglicherweise nie festgeschrieben werden)
  • Zeilen, die eine Mischung aus festgeschriebenen und nicht festgeschriebenen Daten enthalten
  • Verpasste/doppelte Zeilen aufgrund von zuweisungsgeordneten Scans
  • Gemischte ("beschädigte") einzelne (einspaltige) LOB-Werte
  • Fehler 601 – „Scan konnte mit NOLOCK aufgrund von Datenverschiebung nicht fortgesetzt werden“ (Beispiel).

Wenn Ihre primären transaktionsbezogenen Bedenken die Nebeneffekte der Sperrung der Read-Committed-Isolation sind – Blockierung, Locking-Overhead, reduzierte Parallelität aufgrund von Lock-Eskalation usw. – könnten Sie mit einer Isolationsstufe mit Zeilenversionierung wie Read-Committed-Snapshot-Isolation besser bedient sein (RCSI) oder Snapshot-Isolation (SI). Diese sind jedoch nicht kostenlos, und insbesondere Updates unter RCSI weisen einige kontraintuitive Verhaltensweisen auf.

Für Szenarien, die höchste Konsistenzgarantien erfordern, bleibt serialisierbar die einzig sichere Wahl. Für leistungskritische Vorgänge auf schreibgeschützten Daten (z. B. große Datenbanken, die zwischen ETL-Fenstern effektiv schreibgeschützt sind), kann es auch eine gute Wahl sein, die Datenbank explizit auf READ_ONLY zu setzen (gemeinsame Sperren werden nicht genommen, wenn die Datenbank ist schreibgeschützt, und es besteht kein Risiko von Inkonsistenzen).

Es wird auch eine relativ kleine Anzahl von Anwendungen geben, für die Read Uncommitted Isolation die richtige Wahl ist. Diese Anwendungen müssen mit ungefähren Ergebnissen und der Möglichkeit von gelegentlich inkonsistenten, scheinbar ungültigen (in Bezug auf Einschränkungen) oder „wohl beschädigten“ Daten zufrieden sein. Ändern sich Daten relativ selten, ist auch das Risiko dieser Inkonsistenzen entsprechend geringer.

[Siehe den Index für die gesamte Serie]