Ich verwende SQL Server 2005 Express.
In einem Szenario habe ich einen Begin Transaction
Befehl kurz vor einem hinzugefügtINSERT
Anweisung in einer gespeicherten Prozedur . Als ich diese gespeicherte Prozedur ausführte, sperrte sie die gesamte Tabelle und alle gleichzeitigen Verbindungen zeigten bis zu diesem Zeitpunkt eine blockierte Anzeige INSERT
.
Warum wird die gesamte Tabelle gesperrt und wie kann ich dieses Problem in SQL Server 2005 Express beheben?
Bearbeitet
Die Abfrage ist wie folgt:
INSERT INTO <table2> SELECT * FROM <table1> WHERE table1.workCompleted = 'NO'
Antworten:
Diese Antwort kann sich als hilfreich für die ursprüngliche Frage erweisen, dient jedoch in erster Linie dazu, ungenaue Informationen in anderen Posts zu behandeln. Es wird auch ein Abschnitt des Unsinns in BOL hervorgehoben.
Der verknüpfte Abschnitt von BOL lautet:
NB: Ab dem 27.08.2014 wurde BOL aktualisiert, um die oben angegebenen falschen Aussagen zu entfernen.
Zum Glück ist dies nicht der Fall. Wenn dies der Fall wäre, würden Einfügungen in eine Tabelle seriell erfolgen und alle Leser würden für die gesamte Tabelle blockiert, bis die Einfügetransaktion abgeschlossen ist. Das würde SQL Server als Datenbankserver genauso effizient machen wie NTFS. Nicht sehr.
Der gesunde Menschenverstand legt nahe, dass dies nicht möglich ist, aber wie Paul Randall betont: " Tun Sie sich selbst einen Gefallen, vertrauen Sie niemandem ". Wenn Sie niemandem vertrauen können, einschließlich BOL , müssen wir es wohl nur beweisen.
Erstellen Sie eine Datenbank und füllen Sie eine Dummy-Tabelle mit einer Reihe von Zeilen, wobei Sie die zurückgegebene DatabaseId notieren.
Richten Sie einen Profiler-Trace ein, der die Ereignisse sperren: erfasst und gesperrt: freigegeben verfolgt, nach der Datenbank-ID aus dem vorherigen Skript filtert, einen Pfad für die Datei festlegt und die zurückgegebene Trace-ID notiert.
Fügen Sie eine Zeile ein und stoppen Sie die Ablaufverfolgung:
Öffnen Sie die Trace-Datei und Sie sollten Folgendes finden:
Die Reihenfolge der gesperrten Sperren ist:
Die Schlösser werden dann in umgekehrter Reihenfolge freigegeben. Zu keinem Zeitpunkt wurde eine exklusive Sperre für den Tisch erworben.
Ja ist es. SQL Server (und möglicherweise jedes relationale Datenbankmodul) hat keine Voraussicht darüber, welche anderen Stapel möglicherweise ausgeführt werden, wenn eine Anweisung und / oder ein Stapel verarbeitet werden, sodass die Reihenfolge der Sperrenerfassung nicht variiert.
Für dieses spezielle Beispiel werden genau die gleichen Sperren verwendet. Vertrau mir nicht, versuch es!
quelle
Ich mache nicht viel T-SQL-Arbeit, aber ich lese die Dokumentation ...
Dies ist beabsichtigt, wie in der BEGIN TRANSACTION angegeben :
Und wie in der INSERT- Dokumentation angegeben, erhält es eine exklusive Sperre für den Tisch. Die einzige Möglichkeit, ein SELECT für die Tabelle
NOLOCK
durchzuführen, besteht darin , die Isolationsstufe der Transaktion zu verwenden oder festzulegen.quelle