it-swarm.com.de

Was ist "mit (Nolock)" in SQL Server?

Kann jemand die Auswirkungen der Verwendung von with (nolock) auf Abfragen erklären, wenn Sie es verwenden sollten/sollten?

Wenn Sie zum Beispiel eine Bankanwendung mit hohen Transaktionsraten und vielen Daten in bestimmten Tabellen haben, in welchen Abfragetypen wäre Nolock in Ordnung? Gibt es Fälle, in denen Sie es immer/nie benutzen sollten?

567
Andy White

WITH (NOLOCK) entspricht der Verwendung von READ UNCOMMITED als Transaktionsisolationsstufe. Sie haben also das Risiko, eine nicht festgeschriebene Zeile zu lesen, die anschließend zurückgesetzt wird, d. H. Daten, die es nie in die Datenbank geschafft haben. Dies kann zwar verhindern, dass Lesevorgänge durch andere Vorgänge blockiert werden, birgt jedoch ein Risiko. In einer Bankanwendung mit hohen Transaktionsraten wird es wahrscheinlich nicht die richtige Lösung für das Problem sein, das Sie IMHO damit lösen möchten.

428
David M

Die Frage ist, was ist schlimmer:

  • eine Sackgasse, oder
  • ein falscher Wert?

Bei Finanzdatenbanken sind Deadlocks weitaus schlechter als falsche Werte. Ich weiß, das klingt rückwärts, aber höre mich an. Das traditionelle Beispiel für DB-Transaktionen besteht darin, zwei Zeilen zu aktualisieren, von einer zu subtrahieren und zu einer anderen hinzuzufügen. Das ist falsch.

In einer Finanzdatenbank verwenden Sie Geschäftsvorfälle. Das bedeutet, dass jedem Konto eine Zeile hinzugefügt wird. Es ist äußerst wichtig, dass diese Transaktionen abgeschlossen sind und die Zeilen erfolgreich geschrieben wurden.

Es ist keine große Sache, den Kontostand vorübergehend falsch zu machen. Dafür ist die Tagesendabstimmung gedacht. Und es ist weitaus wahrscheinlicher, dass ein Überziehungskredit von einem Konto eingeht, da zwei Geldautomaten gleichzeitig verwendet werden, als aufgrund eines nicht festgeschriebenen Lesevorgangs aus einer Datenbank.

Allerdings hat SQL Server 2005 die meisten Fehler behoben, die NOLOCK erforderlich machten. Wenn Sie also nicht SQL Server 2000 oder eine frühere Version verwenden, sollten Sie es nicht benötigen.

Weiterführende Literatur
Versionierung auf Zeilenebene

160
Jonathan Allen

Das Lehrbuchbeispiel für die legitime Verwendung des Nolock-Hinweises ist die Berichtsprobe für eine Datenbank mit hohem Aktualisierungsgrad OLTP.

Ein aktuelles Beispiel. Wenn eine große US-amerikanische Großbank einen stündlichen Bericht erstellen wollte, um nach den ersten Anzeichen für eine Ausführung auf Stadtebene auf der Bank zu suchen, konnte eine Nolock-Abfrage Transaktionstabellen durchsuchen, in denen Bareinzahlungen und Barabhebungen pro Stadt zusammengefasst wurden. Bei einem solchen Bericht würde der geringe Prozentsatz an Fehlern, die durch rückgängig gemachte Aktualisierungstransaktionen verursacht werden, den Wert des Berichts nicht verringern.

52
saasman

Leider geht es nicht nur darum, nicht festgeschriebene Daten zu lesen. Im Hintergrund werden Sie möglicherweise zweimal die Seiten lesen (im Fall eines Seitensplits), oder Sie verpassen die Seiten möglicherweise vollständig. So können Ihre Ergebnisse grob verzerrt sein.

Check out Itzik Ben-Gans Artikel . Hier ist ein Auszug:

"Mit dem NOLOCK-Hinweis (oder dem Festlegen der Isolationsstufe der Sitzung auf READ UNCOMMITTED) teilen Sie SQL Server mit, dass Sie keine Konsistenz erwarten. Es gibt also keine Garantien. Beachten Sie jedoch, dass" inkonsistente Daten "nicht nur das bedeuten Möglicherweise werden nicht festgeschriebene Änderungen angezeigt, die später zurückgesetzt wurden, oder Datenänderungen in einem Zwischenzustand der Transaktion. Dies bedeutet auch, dass in einer einfachen Abfrage, die alle Tabellen-/Indexdaten durchsucht, SQL Server möglicherweise Daten verliert die Scan-Position, oder Sie erhalten möglicherweise zweimal dieselbe Zeile . "

52
sqlbelle

Sie sind sich nicht sicher, warum Sie Finanztransaktionen nicht in Datenbanktransaktionen einbinden (z. B. wenn Sie Geld von einem Konto auf ein anderes überweisen - Sie schreiben nicht jeweils eine Seite der Transaktion fest - aus diesem Grund gibt es explizite Transaktionen). Selbst wenn Ihr Code auf Geschäftsvorgänge beschränkt ist, können alle Transaktionsdatenbanken im Falle von Fehlern oder Fehlern implizite Rollbacks ausführen. Ich denke, diese Diskussion geht Ihnen weit über den Kopf.

Wenn Sie Probleme beim Sperren haben, implementieren Sie die Versionierung und bereinigen Sie Ihren Code.

Keine Sperre gibt nicht nur falsche Werte zurück, sondern auch Phantomdatensätze und -duplikate.

Es ist ein weit verbreitetes Missverständnis, dass Abfragen dadurch immer schneller ausgeführt werden. Wenn es keine Schreibsperren für eine Tabelle gibt, spielt dies keine Rolle. Wenn die Tabelle Sperren enthält, kann dies die Abfrage beschleunigen, aber es gibt einen Grund, warum Sperren überhaupt erfunden wurden.

Aus Fairnessgründen gibt es hier zwei spezielle Szenarien, in denen ein Nolock-Hinweis nützlich sein kann

1) SQL Server-Datenbank vor 2005, die lange Abfragen für die aktive OLTP -Datenbank ausführen muss. Dies ist möglicherweise die einzige Möglichkeit

2) Schlecht geschriebene Anwendungen, die Datensätze sperren und die Kontrolle an die Benutzeroberfläche und die Leser zurückgeben, werden auf unbestimmte Zeit blockiert. Nolock kann hier hilfreich sein, wenn die Anwendung nicht repariert werden kann (Drittanbieter usw.) und die Datenbank entweder älter als 2005 ist oder die Versionierung nicht aktiviert werden kann.

30
Andrew

NOLOCK ist gleichbedeutend mit READ UNCOMMITTED, jedoch sagt Microsoft, dass Sie es nicht für UPDATE oder DELETE Anweisungen verwenden sollten:

Für UPDATE- oder DELETE-Anweisungen: Diese Funktion wird in einer zukünftigen Version von Microsoft SQL Server entfernt. Vermeiden Sie es, diese Funktion in neuen Entwicklungsarbeiten zu verwenden, und planen Sie, Anwendungen zu ändern, die diese Funktion derzeit verwenden.

http://msdn.Microsoft.com/en-us/library/ms187373.aspx

Dieser Artikel bezieht sich auf SQL Server 2005, sodass die Unterstützung für NOLOCK vorhanden ist, wenn Sie diese Version verwenden. Um Ihren Code zukunftssicher zu machen (vorausgesetzt, Sie verwenden Dirty Reads), können Sie dies in Ihren gespeicherten Prozeduren verwenden:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

23
Seibar

Sie können es verwenden, wenn Sie nur Daten lesen und es Ihnen egal ist, ob Sie Daten zurückerhalten, die noch nicht festgeschrieben wurden.

Es kann bei einer Leseoperation schneller sein, aber ich kann nicht wirklich sagen, um wie viel.

Im Allgemeinen empfehle ich, es nicht zu verwenden - das Lesen nicht festgeschriebener Daten kann bestenfalls etwas verwirrend sein.

19
marc_s

Ein anderer Fall, in dem es normalerweise in Ordnung ist, ist eine Berichtsdatenbank, in der Daten möglicherweise bereits veraltet sind und Schreibvorgänge einfach nicht stattfinden. In diesem Fall sollte die Option jedoch vom Administrator auf Datenbank- oder Tabellenebene festgelegt werden, indem die Standardisolationsstufe geändert wird.

Im allgemeinen Fall: Sie können es verwenden, wenn Sie sehr sicher sind, dass es in Ordnung ist, alte Daten zu lesen. Das Wichtige ist, dass es sehr einfach ist, das falsch zu verstehen . Sind Sie beispielsweise sicher, dass sich zum Zeitpunkt des Schreibens der Abfrage keine Änderungen in der Datenbank ergeben, um diese Aktualisierungen wichtiger zu machen?

Ich werde auch 2. die Vorstellung, dass es wahrscheinlich keine gute Idee in Banking App ist. Oder Inventar App. Oder wo immer Sie über Transaktionen nachdenken.

17
Joel Coehoorn

Einfache Antwort - wenn Ihre SQL keine Daten ändert und Sie eine Abfrage haben, die andere Aktivitäten stören könnte (über Sperren).

Es lohnt sich, Abfragen zu berücksichtigen, die für Berichte verwendet werden, insbesondere wenn die Abfrage länger als beispielsweise 1 Sekunde dauert.

Dies ist besonders nützlich, wenn Sie Berichte vom Typ OLAP verwenden, die für eine OLTP -Datenbank ausgeführt werden.

Die erste Frage ist jedoch: "Warum mache ich mir darüber Sorgen?" Nach meiner Erfahrung wird das Standard-Sperrverhalten häufig verfälscht, wenn sich jemand im Modus "Alles ausprobieren" befindet, und dies ist ein Fall, bei dem unerwartete Folgen nicht unwahrscheinlich sind. Zu oft handelt es sich um eine vorzeitige Optimierung, die zu leicht "nur für den Fall" in eine Anwendung eingebettet werden kann. Es ist wichtig zu verstehen, warum Sie es tun, welches Problem es löst und ob Sie das Problem tatsächlich haben.

14
dkretz

Meine 2 Cent - es ist sinnvoll, WITH (NOLOCK) zu verwenden, wenn Sie Berichte generieren müssen. Zu diesem Zeitpunkt würden sich die Daten kaum ändern und Sie würden diese Datensätze nicht sperren wollen.

9
SoftwareGeek

Wenn Sie Finanztransaktionen abwickeln, sollten Sie nolock niemals verwenden. nolock wird am besten verwendet, um aus großen Tabellen mit vielen Aktualisierungen auszuwählen, und es ist Ihnen egal, ob der Datensatz, den Sie erhalten, möglicherweise veraltet ist.

Bei Finanzaufzeichnungen (und fast allen anderen Aufzeichnungen in den meisten Anwendungen) würde nolock Chaos anrichten, da Sie möglicherweise Daten aus einem Datensatz zurücklesen könnten, in den geschrieben wurde, ohne die richtigen Daten zu erhalten.

8
Andrew Hare

Kurze Antwort:

Verwenden Sie niemals WITH (NOLOCK).

Lange Antwort:

NOLOCK wird oft als magische Methode genutzt, um das Lesen von Datenbanken zu beschleunigen. Ich versuche jedoch, es nach Möglichkeit nicht zu verwenden.

Die Ergebnismenge kann noch nicht festgeschriebene Zeilen enthalten, die häufig später zurückgesetzt werden.

Ein Fehler oder eine Ergebnismenge kann leer sein, Zeilen fehlen oder dieselbe Zeile mehrmals anzeigen.

Dies liegt daran, dass andere Transaktionen Daten verschieben, während Sie sie lesen.

READ COMMITTED fügt ein zusätzliches Problem hinzu, bei dem Daten in einer einzelnen Spalte beschädigt werden und mehrere Benutzer gleichzeitig dieselbe Zelle ändern.

Es gibt auch andere Nebenwirkungen, die dazu führen, dass Sie die erhoffte Geschwindigkeitssteigerung aufgeben.

Es kann argumentiert werden, dass es in Ordnung ist, es an Orten zu verwenden, an denen Sie damit durchkommen können, aber worum geht es? Ich kann mir keine Situation vorstellen, in der beschädigte Daten akzeptabel sind.

Verwenden Sie niemals NOLOCK.

(je)

7

Ich habe verwendet, um eine "nächste Charge" für Dinge, die zu tun sind, abzurufen. In diesem Fall spielt es keine Rolle, um welches Element es sich handelt, und ich habe viele Benutzer, die dieselbe Abfrage ausführen.

7
Otávio Décio

Verwenden Sie nolock, wenn Sie mit den "schmutzigen" Daten einverstanden sind. Dies bedeutet, dass nolock auch Daten lesen kann, die gerade geändert werden, und/oder Daten, die noch nicht festgeschrieben wurden.

Es ist im Allgemeinen keine gute Idee, es in einer Umgebung mit hohen Transaktionen zu verwenden. Aus diesem Grund ist es keine Standardoption für Abfragen.

6
Learning

Ich benutze mit (Nolock) Hinweis vor allem in SQLServer 2000-Datenbanken mit hoher Aktivität. Ich bin jedoch nicht sicher, ob es in SQL Server 2005 benötigt wird. Ich habe diesen Hinweis kürzlich in einem SQL Server 2000 auf Anforderung des Datenbankadministrators des Clients hinzugefügt, da er viele SPID-Datensatzsperren festgestellt hat.

Alles, was ich sagen kann, ist, dass die Verwendung des Hinweises uns NICHT geschadet hat und das Sperrproblem anscheinend selbst gelöst hat. Der DBA bei diesem bestimmten Kunden bestand grundsätzlich darauf, dass wir den Hinweis verwenden.

Übrigens, die Datenbanken, mit denen ich mich beschäftige, sind Back-Ends für medizinische Anspruchssysteme in Unternehmen, daher sprechen wir in vielen Verknüpfungen über Millionen von Datensätzen und über 20 Tabellen. Normalerweise füge ich einen WITH (nolock) -Hinweis für jede Tabelle im Join hinzu (es sei denn, es handelt sich um eine abgeleitete Tabelle. In diesem Fall können Sie diesen bestimmten Hinweis nicht verwenden.)

6
user52212

Die einfachste Antwort ist eine einfache Frage: Müssen Ihre Ergebnisse reproduzierbar sein? Wenn ja, ist NOLOCKS unter keinen Umständen geeignet

Wenn Sie keine Wiederholbarkeit benötigen, ist nolocks möglicherweise hilfreich, insbesondere wenn Sie nicht die Kontrolle über alle Prozesse haben, die eine Verbindung zur Zieldatenbank herstellen.

4
Ed Green