Beste Situation für die Verwendung der Isolationsstufe READ UNCOMMITTED


10

Wie wir alle wissen, ist READ UNCOMMITTED die niedrigste Isolationsstufe, in der Dinge wie Dirty Reads und Phantom Reads auftreten können. Wann ist der beste Zeitpunkt, um diese Isolationsstufe zu verwenden, und aus welchen Gründen könnte sie verwendet werden?

Eigentlich habe ich die Antworten vorher gelesen, aber ich konnte sie nicht vollständig verstehen, weil es nicht genug Beispiele gab.

Antworten:


20

Ich verwende READ_UNCOMMITTED(oder NOLOCK) beim Abfragen von Produktionsdatenbanken von SSMS, aber nicht routinemäßig vom Anwendungscode. Diese Vorgehensweise (zusammen mit einem MAXDOP 1-Abfragehinweis) trägt dazu bei, dass gelegentliche Abfragen für die Datenanalyse und Fehlerbehebung keine Auswirkungen auf die Produktionsauslastung haben, da die Ergebnisse möglicherweise nicht korrekt sind.

Leider sehe READ_UNCOMMITTED/ werde ich NOLOCKim Produktionscode häufig verwendet, um ein Blockieren auf Kosten der Datenintegrität zu vermeiden. Die richtige Lösung ist eine Isolationsstufe für die Zeilenversionierung ( SNAPSHOToder READ_COMMITTEDmit der READ_COMMITTED_SNAPSHOTDatenbankoption ON) und / oder die Beachtung der Abfrage- und Indexoptimierung.

Ich habe kürzlich einen Prozess überprüft, bei dem die einzige Änderung darin bestand, ihn zu entfernen, NOLOCKda er manchmal falsche Ergebnisse lieferte. Das Entfernen NOLOCKwar eine gute Sache, aber da ich wusste, dass verpasste oder duplizierte Zeilen normalerweise beim Scannen der Zuordnungsreihenfolge großer Tabellen auftreten, schlug ich auch eine Umgestaltung vor, um eine UNION ALLTechnik zur Förderung einer effizienten Indexnutzung zu verwenden. Die Abfrage wird jetzt in wenigen Millisekunden mit korrekten Ergebnissen ausgeführt, dem besten aller Welten.


7

Ich denke, es ist unter bestimmten Umständen in Ordnung , solange Sie die Konsequenzen akzeptieren und keine anderen Optionen haben.

Für andere Optionen würde ich die Leute dazu drängen, Read Committed Snapshot Isolation (RCSI) für neue Anwendungen oder SNAPSHOT ISOLATION (SI) für ältere Anwendungen zu verwenden, bei denen Sie mit RCSI nicht einfach die gesamte Codebasis auf Rennbedingungen testen können.

Diese passen jedoch möglicherweise nicht gut zusammen. Möglicherweise müssen Sie zusätzliche Zeit damit verbringen, Tempdb zu lieben und zu pflegen, und sicherstellen, dass niemand eine offene Transaktion hinterlässt, durch die der Versionsspeicher (und Tempdb) wachsen und die Festplatte füllen.

Wenn Sie keinen DBA haben oder jemanden, dessen Aufgabe es ist, Ihren SQL Server zu überwachen und zu verwalten, können diese Optionen gefährlich sein. Im Allgemeinen hat nicht jeder die volle Kontrolle über den Code, der an seinen Server gesendet wird, wo er die Verbindungszeichenfolge oder den Code ändern kann, um nach SI für Problemabfragen zu fragen.

Außerdem haben die meisten Benutzer keine Sperrprobleme mit ihrer gesamten Anwendung . Sie haben Probleme mit der Berichterstellung über OLTP-Daten. Wenn Sie die Kompromisse von NOLOCK / RU im Austausch für Berichte akzeptieren können, die nicht von Autoren blockiert wurden, entscheiden Sie sich dafür.

Stellen Sie einfach sicher, dass Sie verstehen, was das bedeutet. Dies bedeutet nicht, dass Ihre Abfrage keine Sperren akzeptiert, sondern dass die von anderen Abfragen aufgehobenen Sperren nicht berücksichtigt werden.

Und natürlich, wenn Ihr Problem das Sperren von Writern / Writern ist, ist die einzige Option, die helfen wird, SI, aber es würde unglaublich viel Entwicklerarbeit erfordern, um dies mit Fehlerbehandlung usw. richtig zu implementieren.


5
Und wenn das Problem wirklich nur darin besteht, über OLTP-Daten zu berichten, verlagern Sie diese auf eine schreibgeschützte Sekundärseite (AG, Protokollversand, Replikation oder Roll-Your-Own).
Aaron Bertrand

3
@ AaronBertrand Und dann hätten sie einen zweiten Server zu überwachen;)
Erik Darling

5

IMHO ist der einzige gültige Anwendungsfall für READ UNCOMMITTED auf einem modernen System das Debuggen einer Sitzung von einer anderen in der Entwicklung, sodass Sie sehen können, was es tut, während z. B. ein gespeicherter Prozess noch ausgeführt wird. Es würde normalerweise niemals in einem Produktionssystem verwendet werden. Es mag einen kleinen Leistungsgewinn geben, aber auf lange Sicht wird es sich nie lohnen.


3

Wir verwenden es ständig im Gesundheitswesen.

Es ist erstaunlich selten, dass sich einzelne Datenzeilen während der Abfrage ändern, und das Lese- / Schreibverhältnis liegt bei 10.000 / 1 - und die meisten davon sind Einfügungen, keine Aktualisierungen. Wenn die Laborschnittstelle beispielsweise die Laborergebnisse eines Patienten in die Datenbank schreibt, werden sich diese Werte niemals ändern.

Wenn Daten tun ändern, ändert es eine Zeile zu einem Zeitpunkt. Niemand aktualisiert ganze Spalten (außer einem DBA, wenn sie wirklich schlecht sind).

Auf der anderen Seite führen wir eine Reihe von Abfragen durch, um nach Dingen wie Patienten zu suchen, die innerhalb von 72 Stunden oder weniger in die Notaufnahme zurückkehren, was die Tabellen absolut hämmert.

In 10 Jahren SQL im Gesundheitswesen habe ich noch nie einen gesehen Rollback Transaction. Ich möchte ein- und aussteigen, ohne die Endbenutzererfahrung zu beeinträchtigen. Wenn es ein hohes Risiko gibt, die OLTP-Datenbank zu verlangsamen, und ein geringes Risiko, schlechte Daten zu erhalten, werde ich NOLOCK.

Sollen wir es benutzen? Vielleicht, vielleicht nicht. Im Allgemeinen würde ich nicht sagen, dass viele der Anwendungsdatenbanken, an denen ich gearbeitet habe, gut gestaltet sind. Sie sind normalerweise voller Anti-Muster.


4
Nur zu Ihrer Information, es ist möglich, teilweise geschriebene Zeilen mit nolock zu lesen.
Max Vernon

1
Uff! Ich muss wirklich meinen Chef dazu bringen, mir einen anderen Server zu kaufen, damit ich dieses Zeug protokollieren kann ...
James

3
Sie könnten an diesem raffinierten Blog-Beitrag von Paul White über READ UNCOMMITTED interessiert sein, insbesondere an dem Abschnitt "Reading Corrupt Data": The Read Uncommitted Isolation Level
Josh Darnell

1

READ_UNCOMMITTED/NOLOCKist eine gute Option, wenn die Genauigkeit der Daten nicht wirklich das Hauptziel ist. Manchmal, wenn nur eine ungefähre Gesamtanzahl erforderlich ist. Zum Beispiel: Es gibt gespeicherte Prozeduren, mit denen entweder INSERT- oder UPDATE-Tabellen erstellt werden. Manchmal ist die Anzahl der zu aktualisierenden oder einzufügenden Datensätze sehr groß (Tausende von Datensätzen). Während dieser gespeicherten Prozedur ausgeführt wird , wir eine einfache Auswahlabfrage mit ausführen können NOLOCKauf der Zieltabelle in regelmäßigen Abständen , um zu sehen , ob es reibungslos fortschreitet (Für eine Update - Abfrage, wenn Sie eine Statusänderung Spalte für Datensätze aktualisiert werden können wir diese Spalte verwenden ausführen group byAbfrage mit NOLOCKum festzustellen, ob sich die Anzahl der Statusänderungen ständig ändert).


0

Beachten Sie, dass READ UNCOMMITTED zusätzliche Konsistenzprobleme mit sich bringt, nicht nur Dirty Reads. Abhängig von der Zugriffsmethode können Sie Zeilen verpassen oder sogar dieselbe Zeile mehrmals lesen. Wenn Sie an den Details interessiert sind, lesen Sie den Artikel von Itzik Ben-Gan


3
Das mehrmalige Fehlen und Lesen von Zeilen ist auch auf der Standardebene "Festgeschriebenes Lesen" möglich. Wenn eine Indexschlüsselspalte während des Scans aktualisiert wird und verschoben wird.
Martin Smith

Die Nebendiskussion zu dieser Antwort wurde in den Chat verschoben .
Paul White 9
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.