Wenn ich eine SQL Server-Datenbank über ein Netzwerk mit hoher Latenz einzeln aufrufe, treten aufgrund dieser Latenz Tabellensperren auf? Angenommen, ich frage Tabelle A nach einigen Datensätzen ab, und SQL Server muss diese Daten über ein langsames Netzwerk zurückgeben. Besteht eine Lesesperre für Tabelle A, während der Server die Antwort über das Netzwerk sendet, oder gibt SQL Server die Sperre vor dem Senden frei die Antwort?
Würde die Antwort auch je nach Größe der Antwort variieren? Wenn es nur ein paar KB gegenüber mehreren hundert MB zurückgeben muss, würde das einen Unterschied machen?
Das Erstellen einer expliziten Transaktion, das Ausführen von Abfragen und das Schließen der Transaktion würde offensichtlich dazu führen, dass die Tabellen gesperrt werden, da die Dauer der Transaktion mit meiner Latenz korreliert.
quelle
nolock
Hinweis angeben , wird immer eine Sperre angezeigt . Die Latenz bestimmt nur, wie lange die Sperre gehalten wird.nolock
, werden Sie noch Schlösser bekommenUnless you specify a nolock hint, there will always be a lock.
<- Dies impliziert, dass bei Verwendung von nolock möglicherweise keine Sperren vorhanden sind. Ich habe nur geklärt.Antworten:
Dies ist nicht genau, es hängt von der Isolationsstufe ab.
Standardmäßig
READ COMMITTED
werden für die Dauer der Anweisungsausführung keine Sperren gehalten.READ COMMITTED
Keine Lesekonsistenz auf Anweisungsebene. Die einzige Garantie besteht darin, dass Sie keine nicht festgeschriebenen Daten lesen können. Eine gemeinsam genutzte Sperre wird erfasst und gehalten, um die Zeile zu lesen, und dann freigegeben.Es sei denn, Sie haben LOB-Typen.
LOB-Typen, die möglicherweise sehr groß sind, können nicht gepuffert werden. Eine gemeinsam genutzte Sperre muss erworben und gehalten werden, bis die Anweisung vollständig ist, was im Wesentlichen zu einem
REPEATABLE READ
Verhalten bei führtREAD COMMITTED
.Die Latenz verursacht nicht die Tabellensperre, nein. Wenn jedoch eine Tabellensperre erworben wurde, wird diese durch die Latenz verlängert.
Um jemanden zu zitieren, der die Mechanik besser kennt als ich ( @RemusRusanu ):
Wenn die Ergebnisse nicht so schnell verbraucht werden, wie SQL Server sie liefern kann, sei es aufgrund des Clients oder des Netzwerks,
ASYNC_NETWORK_IO
häufen sich die Wartezeiten. Dies hat, um es noch einmal zu wiederholen, keinen Einfluss auf die erworbenen Sperren, sondern nur auf die Dauer, für die sie gehalten werden.quelle
Die Antwort von Mark hat viel von meiner Verwirrung beseitigt, aber ich wollte meine Ergebnisse veröffentlichen, nachdem ich dies mit NetBalancer getestet hatte, um die Latenz zu emulieren.
Ich ließ meinen lokalen Computer einen Remote-SQL-Server aufrufen und in einer kleinen Transaktion sowohl SELECT- als auch INSERT-Anweisungen für eine Tabelle ausführen. Auf dem Remotecomputer stellte ich eine Verbindung zur lokalen SQL-Instanz her und durchlief die Tabelle sys.dm_tran_locks wiederholt mit einer WHILE-Schleife, um nach Sperren für die Tabelle zu suchen, die ich geändert und aus der ich gelesen habe. Ich habe NetBalancer auf dem Server installiert und damit die Netzwerklatenz für die Netzwerkverbindung des Servers emuliert.
Folgendes habe ich gefunden:
Daraus schließe ich, dass die Latenz keine Rolle spielt, solange die Daten in den Netzwerkpuffer passen. Wenn SQL viele Daten im Netzwerkpuffer ablegen muss, führt die Latenz dazu, dass dieser Puffer gesichert wird, und SQL speichert die Tabellensperren, bis das gesamte Abfrageergebnis im Puffer abgelegt werden kann.
quelle
Wenn eine Abfrage von SQL Server ausgelöst und abgeschlossen wird, werden die Ergebnisse erstellt. Legen Sie sie in den Ausgabepuffer und senden Sie sie an den Client, der dann das Ergebnis aus dem Ausgabepuffer abruft. SQL Server gibt die von der Abfrage gehaltenen Sperren nur dann frei, wenn eine Bestätigung vom Client eingeht. Dies kann zu Blockierungen führen.
Bearbeiten: Evan Sie können auf diesen MS-Support-Artikel verweisen
In Abschnitt 3
Durch eine SPID verursachte Blockierung, deren entsprechende Clientanwendung nicht alle Ergebniszeilen vollständig abgerufen hat
Nach dem Senden einer Abfrage an den Server müssen alle Anwendungen alle Ergebniszeilen sofort vollständig abrufen. Wenn eine Anwendung nicht alle Ergebniszeilen abruft, können Sperren in den Tabellen verbleiben, die andere Benutzer blockieren. Wenn Sie eine Anwendung verwenden, die SQL-Anweisungen transparent an den Server sendet, muss die Anwendung alle Ergebniszeilen abrufen. Wenn dies nicht der Fall ist (und dies nicht konfiguriert werden kann), können Sie das Blockierungsproblem möglicherweise nicht beheben. Um das Problem zu vermeiden, können Sie schlecht verhaltene Anwendungen auf eine Berichterstellungs- oder Entscheidungsunterstützungsdatenbank beschränken.
quelle
SELECT *
davon in anREAD COMMITTED
in einer SSMS Verbindung, Monitor Schlösser von einem anderen. Wie viele Schlösser sehen Sie zu irgendeinem Zeitpunkt?