Ich benutze SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
in den meisten meiner allgemeinen SQL-Abfragen, hauptsächlich, weil dies mir beim ursprünglichen Erlernen der Sprache eingeflößt wurde.
Nach meinem Verständnis verhält sich diese Isolationsstufe genauso, WITH (NO LOCK)
wie ich sie jedoch immer nur benutze SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.
- Gibt es überhaupt eine Zeit , die ich verwenden soll
WITH (NO LOCK)
überSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
. - Verhindert es,
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
dass andere Benutzer aus den von mir gelesenen Tabellen ausgeschlossen werden? - Wenn
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
zum Stoppen von Sperren verwendet wird, ich aber nur Daten lese, wozu dient es dann? Sind es nur systemintensive Abfragen, die Sperren erzeugen würden? Lohnt es sich, sie zu verwenden, wenn Abfragen ausgeführt werden, die in etwa 5-10 Sekunden zurückkehren würden? - Mir wurde gesagt,
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
dass ich beim Lesen von Daten, die für Aktualisierungen verwendet werden, keine Daten verwenden soll, vermutlich, um die Aktualisierung schmutziger Daten zu vermeiden. Wäre das der einzige Grund? - Mit der Art der Datenbank, an der ich arbeite, gibt es eine Produktions- und Testumgebung. Wir werden sehr selten die Produktionsumgebung abfragen, aber wenn ich muss, werde ich in der Regel
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
in meiner Abfrage verwenden. Ich verstehe, dass Dirty Reads damit möglich sind. Abgesehen davon, dass Sie Daten zurückerhalten, die möglicherweise nicht in der Datenbank gespeichert werden (und daher meine Ergebnisse verwerfen), welche anderen Arten von "Dirty Reads" könnten möglich sein?
Entschuldigung für die Massenfragen.
READ UNCOMMITTED
überall, in genau der gleichen Art und Weise , wie ich nicht verwenden würdeWITH (NOLOCK)
überall (sie sind im Wesentlichen die gleiche Sache) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhereAntworten:
Es ist schrecklich, dass du es so gelernt hast (sorry!).
READ UNCOMMITTED
Lass uns jede Zeile lesen, ja. Selbst diejenigen , die derzeit verwendet werden , in einemINSERT
,UPDATE
,DELETE
Betrieb. Dies ist sehr nützlich, wenn Sie sich einige Daten oder unternehmenskritischeSELECT
Anweisungen ansehen möchten, bei denen ein Block sehr schädlich wäre.In der Tat riskieren Sie Ihre Integrität. Es kann vorkommen, dass Sie eine Zeile gelesen haben, die gerade zum Löschen oder Ändern verwendet wird. Es kann auch vorkommen, dass Sie einen falschen Wert gelesen haben. Das mag wirklich ungewöhnlich sein, aber es kann passieren. Was meine ich damit
nvarchar
Stellen Sie sich eine Zeile vor, die sehr breit ist (sie enthält viele Spalten mit vielen langen Spalten). In dieser Zeile wird eine Aktualisierung durchgeführt und neue Werte festgelegt. In seltenen Fällen kann es vorkommen, dass Sie nur eine halbe Zeile lesen. Eine andere Sache kann zum Beispiel passieren, wenn ein Benutzer seine Login-Werte ändert. Er ändert seine Mail + Passwort. Die Mail ist bereits festgelegt, das Passwort jedoch nicht. Auf diese Weise haben Sie einen inkonsistenten Zustand.Ich würde vorschlagen, zu vergessen
READ UNCOMMITTED
. Verwenden Sie es einfach dort, wo es wirklich gebraucht wird.Eine andere Alternative für Sie kann darin bestehen, die
READ_COMMITTED_SNAPSHOT
Datenbankoption zu aktivieren, die SieREAD COMMITTED SNAPSHOT
aufgrund der aktivierten Zeilenversionierung in Ihrer Tempdb verwenden können. Auf diese Weise lesen Sie einfach eine andere (ältere) Version einer Zeile. Dadurch werden Ihre Abfragen nicht blockiert. Es kann jedoch vorkommen, dass Sie auch einen alten Wert lesen, aber einen konsistenten alten Wert.Eine andere Idee kann
WITH(READPAST)
stattWITH(NOLOCK)
. Sie werden den alten Zustand der Tabelle lesen (ein bisschen wie in derSNAPSHOT ISOLATION
), aber Sie werden stattdessen alle derzeit gesperrten Zeilen überspringen.quelle
SNAPSHOT ISOLATION
muss zum Einschalten nicht aktiviert seinREAD COMMITTED SNAPSHOT
. Es muss nur dieREAD COMMITTED SNAPSHOT
Datenbankoption aktiviert werden, damit die Zeilenversionierung anstelle der Sperrung für die Lesekonsistenz aktiviert wird und keine fehlerhaften Lesevorgänge erforderlich sind.Wie in der akzeptierten Antwort angegeben, vergessen Sie die Verwendung der Isolationsstufe READ UNCOMMITTED (außer wenn dies wirklich erforderlich ist), da Sie das Risiko eingehen, falsche Daten zu lesen. Aber um den dritten Punkt in Ihrer Frage zu beantworten, gibt es zwei Situationen, die ich für nützlich halte:
Wenn Sie SQL Server SSIS-Pakete schreiben und testen, werden die Schritte des Pakets möglicherweise in eine Transaktion eingeschlossen. Wenn Sie ein Paket testen, indem Sie es Schritt für Schritt im SSIS-Debugger ausführen, möchten Sie möglicherweise Tabellen untersuchen, während die Tabelle gesperrt ist. Mit SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED können Sie mit SQL Server Manager Studio die Tabellen untersuchen, während das Paket debuggt wird.
In SQL Server Manager Studio möchten Sie möglicherweise T-SQL-Code testen, indem Sie ihn in eine Transaktion einschließen, damit Sie die Änderungen rückgängig machen können. Beispielsweise möchten Sie in einer Testdatenbank möglicherweise im Rahmen Ihres Tests den ursprünglichen Status der Daten wiederherstellen. Wenn Sie transaktionsumhüllten Code testen und gesperrte Tabellen überprüfen möchten, während die Transaktion ausgeführt wird, können Sie mit SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED die Werte in einem anderen Fenster überprüfen.
Ich akzeptiere, dass dies ziemlich unklare Verwendungen für READ UNCOMMITTED sind, aber ich fand sie in einer Testumgebung nützlich.
quelle
In den meisten Datenbanken liegt der überwiegende Teil der Aktivitäten, auch das Einfügen, Löschen und Aktualisieren, außerhalb expliziter Transaktionen.
Sicher,
READ UNCOMMITTED
(Dirty Reads) können in diesen Fällen falsche Informationen liefern, aber diese Informationen waren 5 Sekunden früher korrekt.Die Zeiten, in denen fehlerhafte Lesevorgänge zu wirklich schlechten Ergebnissen führen, sind, wenn eine Transaktion fehlschlägt und zurückgesetzt werden muss oder wenn eine Abfrage für zwei Tabellen ausgeführt wird, die normalerweise mithilfe einer expliziten Transaktion zusammen aktualisiert werden.
In einer großen, ausgelasteten Datenbank mit einem Verhältnis von Lesen zu Schreiben von 100 (oder mehr) zu 1 verlangsamt JEDE einzelne (Lese-) Abfrage, die keine fehlerhaften Lesevorgänge verwendet, das System, da sie Daten abrufen und überprüfen muss Bei Sperren UND ist es viel wahrscheinlicher, dass Transaktionen fehlschlagen (normalerweise aufgrund von Deadlocks), was schwerwiegendere Probleme mit der Datenbankintegrität verursachen kann.
Stattdessen macht die Verwendung von Dirty Reads das System VIEL schneller und zuverlässiger (teilweise aufgrund der verbesserten Leistung, die Inkonsistenzen weniger wahrscheinlich macht).
Klar, es gibt Zeiten, in denen sie nicht verwendet werden sollten. Ich mag es nicht, die Datenbank standardmäßig auf die
READ UNCOMMITTED
Isolationsstufe oder sogar auf die expliziteSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Anweisung zu Beginn von SQL-Skripten und SPs einzustellen - es besteht eine zu hohe Wahrscheinlichkeit, dass ein Dirty Read ausgeführt wird, wenn dies nicht der Fall ist. Stattdessen sind die(NOLOCK)
Hinweise ein viel besserer Ansatz, da sie ausdrücklich darauf hinweisen, dass der Programmierer darüber nachgedacht hat, was sie tun, und entschieden, dass Dirty Reads für diese bestimmte Tabelle in dieser bestimmten Abfrage sicher sind.Wenn Sie eine Anwendung programmieren, um Geld von einem Bankkonto auf ein anderes zu überweisen, sollten Sie Dirty Reads nicht verwenden. Für die meisten Anwendungen ist diese Paranoia jedoch nicht erforderlich.
quelle