Warum eine Isolationsstufe READ UNCOMMITTED verwenden?


225

Was sind im Klartext die Nachteile und Vorteile der Verwendung?

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

in einer Abfrage für .NET-Anwendungen und Reporting Services-Anwendungen?

Antworten:


210

Diese Isolationsstufe ermöglicht schmutzige Lesevorgänge. Bei einer Transaktion werden möglicherweise nicht festgeschriebene Änderungen von einer anderen Transaktion vorgenommen.

Um ein Höchstmaß an Isolation aufrechtzuerhalten, erfasst ein DBMS normalerweise Sperren für Daten, was zu einem Verlust der Parallelität und einem hohen Sperraufwand führen kann. Diese Isolationsstufe entspannt diese Eigenschaft.

Vielleicht möchten Sie den Wikipedia-ArtikelREAD UNCOMMITTED lesen, um einige Beispiele zu finden und weiterzulesen.


Vielleicht möchten Sie auch Jeff Atwoods Blog-Artikel darüber lesen, wie er und sein Team in den frühen Tagen von Stack Overflow ein Deadlock-Problem gelöst haben. Laut Jeff:

Aber ist nolockgefährlich? Könnten Sie am Ende ungültige Daten mit read uncommittedon lesen ? Ja, theoretisch. Sie werden keinen Mangel an Astronauten mit Datenbankarchitektur finden, die anfangen, ACID-Wissenschaft auf Sie zu werfen, und fast den Feueralarm des Gebäudes auslösen, wenn Sie ihnen sagen, dass Sie es versuchen möchten nolock. Es ist wahr: Die Theorie ist beängstigend. Aber ich denke Folgendes: "In der Theorie gibt es keinen Unterschied zwischen Theorie und Praxis. In der Praxis gibt es einen."

Ich würde niemals empfehlen, nolock als allgemeines "Gut für was Sie leiden" Schlangenöl-Fix für eventuelle Probleme mit Datenbank-Deadlocks zu verwenden. Sie sollten zuerst versuchen, die Ursache des Problems zu diagnostizieren.

In der Praxis nolockscheint das Hinzufügen zu Abfragen, von denen Sie absolut wissen, dass sie einfach und unkompliziert sind, niemals zu Problemen zu führen ... Solange Sie wissen, was Sie tun.

Eine Alternative zu dem READ UNCOMMITTEDLevel, das Sie vielleicht in Betracht ziehen möchten, ist das READ COMMITTED SNAPSHOT. Nochmals Jeff zitieren:

Snapshots basieren auf einer völlig neuen Methode zur Verfolgung von Datenänderungen. Der Server muss die Daten nicht nur geringfügig logisch ändern, sondern auch physisch anders behandeln. Sobald diese neue Methode zur Verfolgung von Datenänderungen aktiviert ist, wird eine Kopie oder ein Schnappschuss jeder Datenänderung erstellt. Durch das Lesen dieser Snapshots anstelle von Live-Daten in Konfliktzeiten werden beim Lesen keine freigegebenen Sperren mehr benötigt, und die Gesamtleistung der Datenbank kann sich erhöhen.


13
Der Autor scheint zu implizieren, dass das Lesen nicht festgeschrieben / keine Sperre alle zuletzt festgeschriebenen Daten zurückgibt. Meines Wissens nach wird nicht festgeschrieben gelesen, dass der zuletzt festgelegte Wert auch bei nicht festgeschriebenen Transaktionen zurückgegeben wird. In diesem Fall würde das Ergebnis keine Daten "einige Sekunden veraltet" abrufen. Es würde (oder könnte zumindest, wenn die Transaktion, die die von Ihnen gelesenen Daten geschrieben hat, zurückgesetzt wird) Daten abrufen, die nicht existieren oder nie festgeschrieben wurden. Irre ich mich
xr280xr

4
Gute Antwort. Übrigens hat Oracle standardmäßig "Snapshot", seit ich es kenne, wahrscheinlich Jahrzehnte bevor Sql Server es eingeführt hat. Ich war ziemlich enttäuscht, als ich mit SQL Server anfing, und fand heraus, dass alle Parallelitätsprobleme mit "primitiven" Sperrmechanismen gelöst wurden. Ich habe "Read nicht festgeschrieben" in Oracle noch nie gesehen. Und die Praktizierenden sind genauso glücklich wie die Astronauten.
Stefan Steinegger

13
READ UNCOMMITTEDkann auch dazu führen, dass Sie Zeilen zweimal lesen oder ganze Zeilen verpassen . Wenn beim Lesen eine Seitenteilung auftritt, können Sie ganze Datenblöcke übersehen. WITH(NOLOCK)sollte nur verwendet werden, wenn die Genauigkeit der Ergebnisse nicht wichtig ist
Ian Boyd

8
@ DanielNolan, diesen Artikel zu empfehlen ist gefährlich, weil Jeff nicht wusste, was er tat . Das nicht festgeschriebene Lesen ist nur sinnvoll, da das Lesen von Daten niemals geändert wird. Wenn Sie versuchen, damit Tabellen zu lesen, in die geschrieben werden soll, lesen Sie in der Praxis etwas, das zurückgesetzt wird. Es ist nicht nur so, dass Sie Daten lesen, die einige Sekunden alt sind, sondern Sie .................................. ................... ‌ ‌ ........................... ....
Pacerier

5
................................... lesen Daten, die nicht einmal festgeschrieben werden. Das ist genau die Definition von beschädigten Lesevorgängen. Und wenn Sie basierend auf den Ergebnissen dieser nicht festgeschriebenen Lesevorgänge schreiben möchten, werden Sie in der Praxis beschädigte Daten schreiben. In dem Artikel heißt es auch, dass "MySQL, das mit Web-Apps aufgewachsen ist, von Anfang an viel weniger pessimistisch ist als SQL Server". Nicht wahr, SQL Server arbeitet standardmäßig auf der Ebene "Festgeschrieben", während MySQL standardmäßig auf wiederholbaren Lesevorgängen arbeitet, fünf Ebenen entfernt von " Nicht Festgeschrieben" .
Pacerier

36

Dies kann nützlich sein, um den Fortschritt langer Einfügeabfragen zu verfolgen, grobe Schätzungen (wie COUNT(*)oder grob SUM(*)) usw. vorzunehmen .

Mit anderen Worten, die Ergebnisse, die die Dirty-Read-Abfragen zurückgeben, sind in Ordnung, solange Sie sie als Schätzungen behandeln und keine kritischen Entscheidungen auf der Grundlage dieser Schätzungen treffen.


36

Mein bevorzugter Anwendungsfall read uncommitedist das Debuggen von Vorgängen innerhalb einer Transaktion.

Starten Sie Ihre Software unter einem Debugger, während Sie durch die Codezeilen gehen. Dadurch wird eine Transaktion geöffnet und Ihre Datenbank geändert. Während der Code gestoppt ist, können Sie einen Abfrageanalysator öffnen, die Isolationsstufe für nicht festgeschriebene Lesevorgänge festlegen und Abfragen durchführen, um zu sehen, was los ist.

Sie können es auch verwenden, um festzustellen, ob lang laufende Prozeduren hängen bleiben oder Ihre Datenbank korrekt aktualisieren.

Es ist großartig, wenn Ihr Unternehmen gerne zu komplexe gespeicherte Prozeduren erstellt.


6
Mein Unternehmen liebt es, übermäßig komplexe gespeicherte Prozeduren zu erstellen. Was für eine großartige Idee zur Fehlerbehebung!
Brandon

22

Der Vorteil ist, dass es in einigen Situationen schneller sein kann. Der Nachteil ist, dass das Ergebnis falsch sein kann (Daten, die noch nicht festgeschrieben wurden, können zurückgegeben werden) und es keine Garantie dafür gibt, dass das Ergebnis wiederholbar ist.

Wenn Sie Wert auf Genauigkeit legen, verwenden Sie diese nicht.

Weitere Informationen finden Sie auf MSDN :

Implementiert Dirty Read oder Locking der Isolationsstufe 0, was bedeutet, dass keine gemeinsam genutzten Sperren ausgegeben und keine exklusiven Sperren berücksichtigt werden. Wenn diese Option aktiviert ist, können nicht festgeschriebene oder verschmutzte Daten gelesen werden. Werte in den Daten können geändert werden und Zeilen können vor dem Ende der Transaktion im Datensatz angezeigt oder ausgeblendet werden. Diese Option hat den gleichen Effekt wie das Festlegen von NOLOCK für alle Tabellen in allen SELECT-Anweisungen in einer Transaktion. Dies ist die am wenigsten einschränkende der vier Isolationsstufen.


Wie würde sich dies auf die Geschwindigkeit der Abfrage auswirken?
Kip Real

11
@Kip - selectAnweisungen müssen nicht warten, um gemeinsam genutzte Sperren für Ressourcen zu erhalten, die ausschließlich von anderen Transaktionen gesperrt werden.
Jarrod Dixon

15

Wann ist die Verwendung in Ordnung READ UNCOMMITTED?

Faustregel

Gut : Große aggregierte Berichte mit sich ständig ändernden Summen.

Riskant : Fast alles andere.

Die gute Nachricht ist, dass die Mehrheit der schreibgeschützten Berichte in diese Kategorie " Gut " fällt .

Mehr Details...

Ok, um es zu benutzen:

  • Nahezu alle benutzerbezogenen aggregierten Berichte für aktuelle, nicht statische Daten, z. B. Verkäufe seit Jahresbeginn. Es besteht die Gefahr einer Fehlerquote (möglicherweise <0,1%), die viel geringer ist als bei anderen Unsicherheitsfaktoren wie der Eingabe von Fehlern oder nur der Zufälligkeit, wann genau Daten von Minute zu Minute aufgezeichnet werden.

Dies deckt wahrscheinlich den größten Teil dessen ab, was eine Business Intelligence-Abteilung beispielsweise in SSRS tun würde. Die Ausnahme ist natürlich alles mit $ -Zeichen davor. Viele Menschen rechnen mit viel mehr Eifer für Geld als auf die entsprechenden Kernkennzahlen, die erforderlich sind, um den Kunden zu bedienen und dieses Geld zu generieren. (Ich beschuldige Buchhalter).

Wenn riskant

  • Jeder Bericht, der bis in die Detailebene reicht. Wenn dieses Detail erforderlich ist, bedeutet dies normalerweise, dass jede Zeile für eine Entscheidung relevant ist. Wenn Sie eine kleine Teilmenge nicht abrufen können, ohne sie zu blockieren, kann dies aus gutem Grund daran liegen, dass sie gerade bearbeitet wird.

  • Historische Daten. Es macht selten einen praktischen Unterschied, aber während Benutzer verstehen, dass sich ständig ändernde Daten nicht perfekt sein können, sehen sie statische Daten nicht gleich. Schmutzige Lesevorgänge schaden hier nicht, aber gelegentlich können doppelte Lesevorgänge auftreten. Da Sie sowieso keine Blöcke für statische Daten haben sollten, warum sollten Sie das riskieren?

  • Fast alles, was eine Anwendung mit Schreibfunktionen versorgt.

Wenn auch das OK-Szenario nicht OK ist.

  • Verwenden Anwendungen oder Aktualisierungsprozesse große Einzeltransaktionen? Diejenigen, die viele Datensätze, über die Sie berichten, entfernen und dann wieder einfügen? In diesem Fall können Sie NOLOCKdiese Tabellen wirklich für nichts verwenden.

Guter Punkt zu Berichten. Die erste Idee, die mir in den Sinn kam, war, ob ich sie read uncommittedfür Webanwendungen verwenden sollte, wenn der Benutzer ein UI-Raster sieht, in dem die Datengenauigkeit nicht so wichtig ist. Der Benutzer möchte nur einen schnellen Überblick darüber, welche Datensätze möglicherweise vorhanden sind, und möglicherweise mit Paging, Sortieren und Filtern. Nur wenn der Benutzer auf die Schaltfläche Bearbeiten klickt, versuche ich, den aktuellsten Datensatz mit einer strengeren Isolationsstufe zu lesen. Sollte ein solcher Ansatz nicht leistungsmäßig besser sein?
JustAMartin

Ja, ich denke das ist vernünftig. Denken Sie daran, dass das wichtigere Problem darin besteht, sicherzustellen, dass die Daten zwischen dem Drücken der Schaltfläche Bearbeiten und dem Senden nicht von einer anderen Person geändert wurden. Sie können damit umgehen, indem Sie eine Transaktion starten, die die Daten wie abruft select item from things with (UPDLOCK). Geben Sie dort eine kurze Zeitüberschreitung ein, damit der Benutzer benachrichtigt wird, wenn die Sperre nicht schnell erreicht werden kann. So sind Sie nicht nur vor Benutzern, sondern auch vor Entwicklern geschützt. Das einzige Problem dabei ist, dass Sie über Zeitüberschreitungen nachdenken müssen und wie Sie damit in der Benutzeroberfläche umgehen.
Adamantish

6

In Bezug auf die Berichterstellung verwenden wir sie für alle unsere Berichtsabfragen, um zu verhindern, dass eine Abfrage die Datenbanken blockiert. Wir können das tun, weil wir historische Daten abrufen, nicht Daten im Mikrosekundenbereich.


4

Verwenden Sie READ_UNCOMMITTED in Situationen, in denen es sehr unwahrscheinlich ist, dass sich die Quelle ändert.

  • Beim Lesen historischer Daten. zB einige Bereitstellungsprotokolle, die vor zwei Tagen erstellt wurden.
  • Beim erneuten Lesen von Metadaten. zB metadatenbasierte Anwendung.

Verwenden Sie READ_UNCOMMITTED nicht, wenn Sie wissen, dass sich die Quelle während des Abrufvorgangs ändern kann.


1
Ich denke, das Gegenteil trifft zu. Erstens sollten statische Daten ohne Blöcke gut gelesen werden. Wenn es nicht dann haben Sie jetzt blockiert entdeckt gibt es ein wichtiges hängende Transaktion Problem zu beheben. Außerdem erwarten die Benutzer, dass dies bis zur letzten Dezimalstelle übereinstimmt, was auch immer sie für den Jahresbericht des letzten Jahres ausgedruckt haben. Sie erwarten im Allgemeinen nicht dasselbe von Berichten, von denen sie wissen, dass sie sich ständig ändern. Dies gilt nicht für detaillierte, äußerst zeitkritische oder finanzielle Berichte. Wenn jedoch ein Eingabefehler in 1000 tolerierbar ist, ist dies auch der Fall READ UNCOMMITTED.
Adamantish

TLDR: Wenn sich die Daten nicht ändern, brauchen Sie READ UNCOMMITTED nicht, da es sowieso keine Blöcke gibt. Wenn Sie sich irren und es sich ändert, ist es gut, dass Sie Benutzer daran gehindert haben, schmutzigere Daten als erwartet zu erhalten.
Adamantish

Ja, ich stimme @Adamantish hier eher zu - Sie können READ UNCOMMITTEDin Situationen, in denen Ihre Daten aktiv verwendet werden, von den meisten profitieren und möchten die Serverlast reduzieren, um mögliche Deadlocks und Transaktions-Rollbacks zu vermeiden, nur weil einige Benutzer unachtsam missbraucht wurden. " Schaltfläche "Aktualisieren" auf einer Webseite mit einem Datagrid. Benutzern, die mehrere Datensätze gleichzeitig anzeigen, ist es normalerweise egal, ob die Daten etwas veraltet oder teilweise aktualisiert sind. Nur wenn ein Benutzer einen Datensatz bearbeiten möchte, möchten Sie ihm möglicherweise die genauesten Daten geben.
JustAMartin

2

Dies gibt Ihnen schmutzige Lesevorgänge und zeigt Ihnen Transaktionen an, die noch nicht festgeschrieben wurden. Das ist die naheliegendste Antwort. Ich denke nicht, dass es eine gute Idee ist, dies nur zu verwenden, um Ihre Lesevorgänge zu beschleunigen. Es gibt andere Möglichkeiten, dies zu tun, wenn Sie ein gutes Datenbankdesign verwenden.

Es ist auch interessant festzustellen, was nicht passiert. READ UNCOMMITTED ignoriert nicht nur andere Tabellensperren. Es verursacht auch keine eigenen Sperren.

Angenommen, Sie generieren einen großen Bericht oder migrieren Daten aus Ihrer Datenbank mithilfe einer großen und möglicherweise komplexen SELECT-Anweisung. Dies führt zu einer gemeinsam genutzten Sperre, die für die Dauer Ihrer Transaktion möglicherweise zu einer gemeinsam genutzten Tabellensperre eskaliert wird. Andere Transaktionen können aus der Tabelle gelesen werden, Aktualisierungen sind jedoch nicht möglich. Dies kann eine schlechte Idee sein, wenn es sich um eine Produktionsdatenbank handelt, da die Produktion möglicherweise vollständig gestoppt wird.

Wenn Sie READ UNCOMMITTED verwenden, setzen Sie keine gemeinsame Sperre für die Tabelle. Möglicherweise erhalten Sie das Ergebnis aus einigen neuen Transaktionen oder nicht, je nachdem, wo in der Tabelle die Daten eingefügt wurden und wie lange Ihre SELECT-Transaktion gelesen hat. Sie können dieselben Daten auch zweimal abrufen, wenn beispielsweise eine Seitenteilung auftritt (die Daten werden an einen anderen Speicherort in der Datendatei kopiert).

Wenn es für Sie sehr wichtig ist, dass Daten während der Auswahl eingefügt werden können, ist READ UNCOMMITTED möglicherweise sinnvoll. Sie müssen berücksichtigen, dass Ihr Bericht möglicherweise einige Fehler enthält. Wenn er jedoch auf Millionen von Zeilen basiert und nur wenige davon bei der Auswahl des Ergebnisses aktualisiert werden, ist dies möglicherweise "gut genug". Ihre Transaktion kann auch insgesamt fehlschlagen, da die Eindeutigkeit einer Zeile möglicherweise nicht garantiert werden kann.

Ein besserer Weg insgesamt könnte darin bestehen, SNAPSHOT ISOLATION LEVEL zu verwenden, aber Ihre Anwendungen müssen möglicherweise einige Anpassungen vornehmen, um dies zu verwenden. Ein Beispiel hierfür ist, wenn Ihre Anwendung eine Zeile exklusiv sperrt, um zu verhindern, dass andere Benutzer sie lesen und in der Benutzeroberfläche in den Bearbeitungsmodus wechseln. SNAPSHOT ISOLATION LEVEL bringt auch einen erheblichen Leistungsverlust mit sich (insbesondere auf der Festplatte). Sie können dies jedoch überwinden, indem Sie Hardware auf das Problem werfen. :) :)

Sie können auch eine Sicherung der Datenbank wiederherstellen, um Daten zu melden oder in ein Data Warehouse zu laden.


0

Es kann für eine einfache Tabelle verwendet werden, z. B. in einer Nur-Einfügungs-Prüftabelle, in der keine Aktualisierung der vorhandenen Zeile und keine Aktualisierung der anderen Tabelle erfolgt. Der Einsatz ist ein einfacher Einsatz, bei dem keine oder nur eine geringe Wahrscheinlichkeit eines Rollbacks besteht.


-7

Ich benutze jetzt immer READ UNCOMMITTED. Es ist schnell mit den geringsten Problemen. Wenn Sie andere Isolierungen verwenden, werden Sie fast immer auf einige Blockierungsprobleme stoßen.

Solange Sie Felder für die automatische Inkrementierung verwenden und den Einfügungen etwas mehr Aufmerksamkeit schenken als Ihrer Geldstrafe, können Sie sich von blockierenden Problemen verabschieden.

Sie können mit READ UNCOMMITED Fehler machen, aber um ehrlich zu sein, ist es sehr einfach, sicherzustellen, dass Ihre Beilagen vollständig geprüft sind. Beilagen / Updates, die die Ergebnisse einer Auswahl verwenden, sind nur das, worauf Sie achten müssen. (Verwenden Sie hier READ COMMITTED oder stellen Sie sicher, dass Dirty Reads kein Problem verursachen.)

Gehen Sie also zu Dirty Reads (speziell für große Berichte), Ihre Software läuft reibungsloser ...


6
Dies ist sehr ungenau und berührt nur die Oberfläche von Problemen, die bei Nolock auftreten können. Seiten können geteilt werden, Verknüpfungen können fehlschlagen, Sie können nicht vorhandene Daten lesen oder Daten duplizieren. Es gibt keine Möglichkeit, die Verwendung kinderleicht zu machen: Sie können der Genauigkeit von nichts unter dieser Isolationsstufe vertrauen. READ COMMITTED SNAPSHOT ist ein weniger gefährliches "falsches Allheilmittel"
Mark Sowul

@ MarkSowul Die Abwertung dieser Antwort erscheint mir unfair. @Clive war klar, dass er Committedfür Einfügungen und Updates wechseln würde . Wie bei anderen Problemen zeigte er auch das Bewusstsein für Probleme beim Teilen von Seiten, indem er die Verwendung eines Schlüssels für die automatische Inkrementierung erwähnte. Ich stimme ihm zu, dass fast alle Live-Berichte, die nur von einem Menschen gelesen werden sollen, geringfügige Abweichungen bei der letzten Dezimalstelle tolerieren können. Ich würde zustimmen, dass es eine andere Geschichte für detaillierte Auflistungen oder Daten ist, die maschinell gelesen und transformiert werden sollen, und Clive auch.
Adamantish

1
Dieser Kommentar zeigt auch einen Mangel an umfassendem Verständnis der möglichen Probleme, die mit Nolock verbunden sind. "Leichte Abweichungen in der letzten Dezimalstelle" deckt es kaum ab. Sogar das Berühren von "Nur für Einfügungen / Aktualisierungen festgeschriebenes Lesezeichen verwenden" ist als allgemeiner Rat falsch (was ist, wenn es "Einfügen eines Datensatzes, wenn er nicht vorhanden ist" ist?). In jedem Fall ist "[nicht festgeschrieben lesen] schnell mit den geringsten Problemen" kategorisch falsch.
Mark Sowul

Für die Aufzeichnung stimme ich Ihrer Antwort zu, Adamantish: ungefähr genaue Aggregationen und wenig anderes.
Mark Sowul
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.