Erwirbt eine einfache Auswahlabfrage Sperren?


13

Ich bin sehr neu in SQL Server und würde gerne verstehen, ob die folgende, sehr einfache selectAnweisung Sperren zulässt.

Select * from Student;

Bitte betrachten Sie den Fall, in dem die Anweisung nicht in einem begin tranBlock ausgeführt werden würde.


1
Dies ist eine viel kompliziertere Frage, als Sie vielleicht denken. Die Antwort hängt von vielen Faktoren ab (wie hoch ist die Isolationsstufe für Sitzungstransaktionen? Ist die festgeschriebene Snapshot-Isolation für Lesezugriffe aktiviert? Verfügt der gescannte Index über Optionen zum Verhindern von Zeilen- oder Seitensperren?) Und kann sich sogar während der Ausführung der Anweisung ändern (wie viele) Zeilen sind in der Tabelle? Ist die Tabelle partitioniert?). Hier ist ein guter Punkt, um mit dem Lesen zu beginnen.
Jon Seigel

Antworten:


5

Ja, es ist eine gemeinsame Sperre für die Zeilen erforderlich, die standardmäßig gelesen werden (es ist auch eine gemeinsame Absichtssperre für alle Seiten des zu lesenden Clustered-Index erforderlich). Es gibt jedoch Möglichkeiten, dies zu umgehen (SQL Server hat den Nolock-Hinweis). Befindet sich die Anweisung nicht in einem BEGIN TRAN, wird die Sperre freigegeben, nachdem die SELECT-Anweisung ausgeführt wurde.

Weitere Infos finden Sie hier:

http://msdn.microsoft.com/en-us/library/ms184286(v=sql.105).aspx http://www.sqlteam.com/article/introduction-to-locking-in-sql-server


Außerdem können Sie die Transaktionsisolationsstufe so einstellen, dass das Lesen ohne Commit erfolgt.
Zane

1
Wenn der SELECT also zehn Zeilen liest, werden die zehn gemeinsamen Sperren gehalten, bis alle zehn Zeilen gelesen wurden, oder werden sie pro Zeile erfasst und freigegeben?
Ian Warburton

25

Ich würde gerne verstehen, ob die folgende, sehr einfache select-Anweisung Sperren zulässt

Es ist ein weit verbreitetes Missverständnis, dass eine SELECTAbfrage, die auf der Standard- READ COMMITTEDTransaktionsisolationsstufe ausgeführt wird, immer gemeinsame Sperren verwendet, um fehlerhafte Lesevorgänge zu verhindern.

SQL Server kann das Aufheben gemeinsam genutzter Sperren auf Zeilenebene vermeiden, wenn keine Gefahr besteht, nicht festgeschriebene Daten ohne diese zu lesen (obwohl weiterhin IS-Sperren (Intent-Shared) auf höherer Ebene verwendet werden).

Selbst wenn gemeinsam genutzte Zeilensperren verwendet werden (möglicherweise, weil die Seite, auf der sich die Zeile befindet, durch eine andere gleichzeitige Transaktion geändert wurde), können diese lange vor Abschluss der SELECTAnweisung freigegeben werden .

In den meisten Fällen wird die Zeile "entsperrt", bevor der Server die nächste Zeile verarbeitet. Unter bestimmten Umständen werden gemeinsam genutzte Sperren, die auf der Standardisolationsstufe verwendet werden, bis zum Ende der aktuellen Anweisung, jedoch nicht bis zum Ende der Transaktion gespeichert .

Das Überschreiben der aktuellen Isolationsstufe mit dem NOLOCKTabellenhinweis ist fast immer eine schlechte Idee .

Das Sperren ist ein Implementierungsdetail. SQL Server führt bei Bedarf Sperren durch, um sicherzustellen, dass die semantischen Garantien der aktuellen Isolationsstufe eingehalten werden . Es gibt sicherlich Zeiten, in denen es nützlich ist, ein wenig darüber zu wissen, warum Sperren verwendet werden, aber der Versuch, sie vorherzusagen, ist sehr oft kontraproduktiv.

SQL Server bietet eine Vielzahl von Isolationsstufen. Wählen Sie die, die die Garantien und Verhaltensweisen bietet, die Ihre Datenkonsumenten benötigen.

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.