Angenommen, ich habe die folgende lange laufende Abfrage
UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows
Angenommen, die folgende Abfrage wird ausgeführt, während die obige Abfrage ausgeführt wird
SELECT *
FROM [Table1]
Verhindert die erste Abfrage, dass die zweite Abfrage ausgeführt wird, bis die erste Abfrage abgeschlossen ist? Wenn ja, verhindert die erste Abfrage, dass die zweite Abfrage für alle Zeilen oder nur für die in der WHERE-Klausel enthaltenen Zeilen ausgeführt wird?
BEARBEITEN:
Angenommen, die zweite Abfrage lautet
SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
-- the clause in the first query and which has additional matching elements
quelle
SELECT * FROM Table1
wenn das genau das ist, was ich brauche?*
Dies ist für sich genommen eine schlechte Praxis, da bei Änderungen der Tabellenstruktur die Anwendung normalerweise unterbrochen wird (unerwartete Spalten erscheinen im Ergebnis).Edit: Wie @MaxVernon hervorhebt , ist das Folgende in keiner Weise ein Vorschlag, NOLOCK zu verwenden , und ich hätte auch nur erwähnen sollen, die Transaktionsebene auf zu setzen
READ UNCOMMITED
und die negative Konnotation dort stehen zu lassen, alsNOLOCK
zuerst aufzurufen. So wie ursprünglich gepostet:Das schnelle und einfache lautet: "Ja, die erste Abfrage blockiert die zweite Abfrage, es sei denn, ein bestimmter Indexhinweis ist angegeben ( NOLOCK , manchmal als" Dirty Read "bezeichnet) oder die Transaktionsisolationsstufe der zweiten Abfrage ist auf
READ UNCOMMITED
(die identisch funktioniert)." Nein, tut es nicht."In Reaktion auf die zusätzlichen Details in der Frage, die die Aufnahme einer
WITH
Klausel in die zweite beinhaltenSELECT
, die sich gegenseitig ausschließt oder auf andere Weise, werden die Wechselwirkungen zwischen den beiden Abfragen weitgehend gleich sein.Führen Sie in einer separaten Sitzung Folgendes aus:
Sie können die aktuell gehaltenen Sperren überprüfen, indem Sie sie ausführen
sp_lock
, vorzugsweise in einer weiteren separaten Sitzung:Es sollte eine
KEY
Typensperre angezeigt werden, die von der Spid gehalten wird, die die Einfügetransaktion imX
(exklusiven) Modus ausführt , nicht zu verwechseln mit den anderenIX
(absichtlich-exklusiven) Sperren. Die Sperrdokumentation gibt an, dass dieKEY
Sperre zwar bereichsspezifisch ist, jedoch auch verhindert, dass andere Transaktionen die betroffenen Spalten einfügen oder aktualisieren, indem die darin enthaltenen Daten so geändert werden, dass sie in diesen Bereich der ursprünglichen Abfrage fallen. Da die Sperrung selbst exklusiv ist, verhindert die erste Abfrage den Zugriff auf die Ressource durch eine andere gleichzeitige Transaktion. Tatsächlich sind alle Zeilen der Spalte gesperrt, unabhängig davon, ob sie in den von der ersten Abfrage angegebenen Bereich fallen oder nicht.Die
S
Sperre, die von der zweiten Sitzung gehalten wird, bleibt so lange bestehen,WAIT
bis dieX
Sperre aufgehoben wird, wodurch verhindert wird, dass eine andereX
(oder eine andereU
) Sperre für diese Ressource von einer anderen gleichzeitigen Spid übernommen wird, bevor die zweite Sitzung ihre Leseoperation abgeschlossen hat, was die Existenz derS
Sperre rechtfertigt .Jetzt eine Bearbeitung für Klarheit: Wenn ich mich nicht irre, was ein zerstörendes Lesen ist aus der kurzen Beschreibung der hier genannten Risiken ... Bearbeiten 3 : Ich habe realisiert Ich betrachte nicht die Wirkung eines Hintergrund - Checkpoint , der schreibt eine als noch nicht festgeschriebene Transaktion auf Festplatte, also ja, meine Erklärung war irreführend.
In der zweiten Abfrage kann (und wird in diesem Fall) der erste Stapel nicht festgeschriebene Daten zurückgeben. Der zweite Stapel, der in der Standardtransaktionsisolationsstufe von ausgeführt
READ COMMITED
wird, wird erst nach Abschluss eines Commits oder Rollbacks in der ersten Sitzung zurückgegeben.Von hier aus können Sie Ihre Abfragepläne aussehen und die damit verbundenen Sperre Ebenen, aber noch besser, können Sie alles über Schlösser in SQL Server lesen Sie hier .
quelle
WITH (NOLOCK)
diesem Fall wäre eine Warnung zur Verwendung hilfreich. Weitere Informationen finden Sie unter brentozar.com/archive/2011/11/… und brentozar.com/archive/2013/02/… .WITH (NOLOCK)
Hinweis gibt keine schmutzigen Seiten aus dem Speicher zurück, die nicht festgeschrieben wurden. Tatsächlich werden die Zeilen aus der Tabelle gelesen (ob auf der Festplatte oder im Arbeitsspeicher zwischengespeichert), ohne dass die Writer daran gehindert werden, die von der Tabelle verwendeten Seiten zu aktualisieren oder Zeilen hinzuzufügen.