SQL Server-Praxis

NOLOCK: Schnelle Antworten können falsch sein

Untersuchen Sie Dirty Reads mit zwei Sitzungen, verbleibende Sperren und einen sicheren Weg zu korrekten Berichten ohne NOLOCK.

Ein Bericht kann nach zwei Sekunden fertig sein und trotzdem weniger nützlich sein als ein Bericht, der fünf Sekunden wartet. Das gilt besonders dann, wenn seine Summe in keinem bestätigten Datenzustand existiert hat. NOLOCK verändert, welche Daten eine Abfrage sehen darf. Bei Rechnungen, Beständen und betrieblichen Entscheidungen ist das eine fachliche Änderung, keine bloße Beschleunigung.

Das Problem nachvollziehbar zeigen

Verwenden Sie eine Wegwerfdatenbank und zwei Abfragefenster, die beide mit dieser Datenbank verbunden sind. Führen Sie die Vorbereitung einmal aus. Starten Sie danach in Fenster A die Transaktion und lassen Sie sie offen. Führen Sie in Fenster B die NOLOCK-Abfrage aus. Erst anschließend kehren Sie zu A zurück und rollen die Änderung zurück.

CREATE TABLE dbo.NolockDemo (Id int PRIMARY KEY, Balance int NOT NULL);
INSERT dbo.NolockDemo VALUES (1, 100);
BEGIN TRAN;
UPDATE dbo.NolockDemo SET Balance = 900 WHERE Id = 1;
-- Run the reader in window B, then execute:
-- ROLLBACK;
SELECT Balance FROM dbo.NolockDemo WITH (NOLOCK) WHERE Id = 1;

Fenster B kann den Wert 900 lesen, obwohl dieser niemals bestätigt wird. Nach dem Rollback beträgt der bestätigte Kontostand weiterhin 100. Unter sperrbasiertem READ COMMITTED kann eine normale Abfrage warten. Ist READ_COMMITTED_SNAPSHOT eingeschaltet, kann sie stattdessen die zuvor bestätigte Version lesen. Prüfen Sie daher zuerst die Datenbankoption, bevor Sie aus dem beobachteten Verhalten eine Schlussfolgerung ziehen.

Bei mehreren verbundenen Tabellen lässt sich der Fehler schwerer erkennen. Ein Kontostand kann bereits geändert sein, während zugehörige Buchungen noch nicht sichtbar sind. Unter konkurrierenden physischen Änderungen können bei NOLOCK außerdem Zeilen fehlen oder mehrfach gelesen werden. Dass eine Wiederholung die erwartete Summe liefert, beweist nicht die Richtigkeit des vorherigen Ergebnisses. Gerade diese Unregelmäßigkeit erschwert die Fehlersuche im Betrieb.

Die ursprüngliche Wartezeit untersuchen

Auch NOLOCK benötigt bei Kompilierung und Ausführung Schemasicherheitssperren. Eine Schemaänderung kann deshalb die Abfrage blockieren; umgekehrt kann eine lange Abfrage eine Schemaänderung aufhalten. Der Hinweis beseitigt weder CPU-Arbeit noch Sortierauslagerungen, Datenübertragung oder physische Lesezugriffe. Eine verbleibende Wartezeit muss nach ihrer tatsächlichen Ursache untersucht werden.

Erfassen Sie Leser, Hauptblockierer, ausgeführte Anweisungen und Transaktionsalter. Hält Anwendungscode eine Transaktion während einer externen API-Anfrage offen, muss deren Lebensdauer verkürzt werden. Liest der Bericht Millionen irrelevanter Zeilen, sind Filter und Zugriffsweg zu überprüfen. Fordert ein Dashboard die gesamte Historie an, kann eine fachlich geeignete Zusammenfassung helfen. Diese Maßnahmen lösen unterschiedliche Probleme und sollten getrennt bewertet werden.

Legen Sie anschließend fest, welche Konsistenz der Bericht benötigt. Genügt ein bestätigter Zustand je Anweisung? Müssen mehrere Anweisungen denselben Datenstand verwenden? Ist ein ausdrücklich veralteter Berichtsstand zulässig? READ_COMMITTED_SNAPSHOT bietet Anweisungskonsistenz; SNAPSHOT kann Transaktionskonsistenz bieten. Eine lesbare Replik kann gegenüber dem Primärsystem zurückliegen und garantiert nicht automatisch die Konsistenz beliebiger mehrteiliger Abläufe.

Den Hinweis kontrolliert ersetzen

Beginnen Sie mit einem Bericht, dessen Ergebnisse sich unabhängig prüfen lassen. Entfernen Sie NOLOCK in einer repräsentativen Testumgebung, messen Sie Laufzeit und logische Lesezugriffe und erzeugen Sie gleichzeitig Schreiblast. Wenn Zeilenversionierung infrage kommt, prüfen Sie Speicherbedarf, lange Leser und bestehende Schreibtransaktionen. Eine datenbankweite Option betrifft wesentlich mehr als diesen einen Bericht.

Der Abnahmetest sollte das Kontobeispiel wiederholen und sicherstellen, dass der unbestätigte Wert niemals veröffentlicht wird. Ergänzen Sie eine Transaktion über mehrere Tabellen entsprechend dem echten Anwendungspfad. Prüfen Sie eine fachliche Invariante, etwa die Übereinstimmung zwischen Rechnungskopf und Positionen. Ein erfolgreicher HTTP-Status des Berichts genügt dafür nicht.

Dokumentieren Sie Laufzeit und Korrektheit getrennt. Eine tragfähige Lösung liefert unter konkurrierender Last einen akzeptablen bestätigten Zustand innerhalb der benötigten Frist. Schließen Sie die Übungstransaktion ausdrücklich mit ROLLBACK und entfernen Sie die Testtabelle anschließend. NOLOCK darf höchstens eine bewusst akzeptierte Einschränkung für einen konkreten Zweck sein, niemals eine unbemerkte Standardeinstellung in sämtlichen Abfragen.

Technische Referenzen: Microsoft Learn: Table hints · Microsoft Learn: Transaction isolation.

Frage zu diesem Artikel

Haben Sie eine Frage zu diesem Thema?

Beschreiben Sie, was Sie bewerten oder wo Sie nicht weiterkommen. Wir antworten mit einer praktischen Empfehlung.

Inquiries are not enabled in this preview.

Eine Frage zu diesem Artikel stellen