2010-06-25 8 views
48

Ich kann sehen, wie in SQL Server die Sperrung auf Zeilen- und Seitenebene deaktiviert wird, aber ich kann keine Möglichkeit finden, SQL Server dazu zu zwingen, Sperren auf Zeilenebene zu verwenden. Gibt es eine Möglichkeit, SQL Server zu zwingen, Sperren auf Zeilenebene zu verwenden und KEIN Sperren auf Seitenebene zu verwenden?Ist es möglich, Sperren auf Zeilenebene in SQL Server zu erzwingen?

+1

Die Hauptfrage wäre: ** warum ** auf der Erde würden Sie dies in der ersten tun wollen Ort?? –

+3

Ich habe zwei SQL-Anweisungen in einen Deadlock laufen, die ich nicht erwartet habe. Siehe: http://stackoverflow.com/questions/3112699/how-can-i-avoid-a-deadlock-between-these-two-sql-statements – Elan

+0

@marc_s Ich hatte das gleiche Bedürfnis. Weißt du, warum? Ich habe eine SP, die parallel ausgeführt werden muss, und wo ich Code für mehrere Tabellen habe, die von einer großen Anzahl von Zeilen geändert werden sollen. Keine Ahnung, warum dies nicht als ein gültiges und natürliches Bedürfnis angesehen werden sollte. Problem ist, dass es Deadlock in SQL Server verursacht. – Mashrur

Antwort

30

können Sie die ROWLOCK Hinweis verwenden, aber AFAIK SQL entscheiden, kann es zu eskalieren, wenn es auf die Ressourcen zur Neige geht

From the doco:

ROWLOCK Gibt an, dass Zeilensperren genommen sind, wenn Seiten- oder Tabellensperren sind normalerweise genommen. Wenn in Transaktionen angegeben an der SCHNAPPSCHUSS Isolationsstufe betrieben wird, sind Zeilensperren nicht genommen, es sei denn mit ROWLOCK anderen Tabellenhinweise kombiniert ist, die Schlösser erfordern, wie UPDLOCK und HOLDLOCK.

und

Sperrhinweise ROWLOCK, UPDLOCK UND XLOCK die Zeilensperren erwerben Sperren auf Indexschlüssel setzen, anstatt die eigentlichen Datenzeilen. Wenn beispielsweise eine Tabelle einen nicht gruppierten Index hat, und eine SELECT-Anweisung einen Sperrhinweises unter Verwendung durch einen abdeckenden Index gehandhabt wird, eine Sperre auf dem Indexschlüssel erworben in den abdeckenden Index als auf den Daten Reihe in der Basistabelle.

And finally dies in SQL Server 2005 eine ziemlich in die Tiefe gehende Erklärung über Lock Eskalation gibt, die 2008

Es gibt auch in SQL Server geändert wurde, ist, die sehr in die Tiefe:

Locking in The Database Engine (in Bücher online)

So im allgemeinen

UPDATE 
Employees WITH (ROWLOCK) 
SET Name='Mr Bean' 
WHERE Age>93 

Sollten in Ordnung sein, aber je nach dem Indizes und Last auf dem Server kann es zu einer Seitensperre eskaliert enden.

+9

nur zum Hinzufügen, in SQL-Server 2008+ können Sie effektiv sperren Eskalation mit 'ALTER TABLE Tabellenname SET (LOCK_ESCALATION = DEAKTIVIEREN)' –

+0

[basierend auf Ihren Kommentaren zu Remus Rusanu] bedeutet, es gibt nichts, was wir tun können, um eine Zeile zu sperren Alles, wie macht es Oracle? – bjan

+0

@bjan nicht sicher, im Allgemeinen Oracles Snapshot-Natur bedeutet, dass es weniger anfällig für diese Art von Sperranforderungen ist sowieso. Im Allgemeinen würde ich irgendwelche Ruderstockhinweise vermeiden, die es fast nie benötigt wird –

13

Verwenden Sie die ALLOW_PAGE_LOCKS Klausel ALTER/CREATE INDEX:

ALTER INDEX indexname ON tablename SET (ALLOW_PAGE_LOCKS = OFF); 
+4

Eine wichtige Anmerkung ist, dass dies zu einer Tabellensperre eskalieren kann, wenn es auf Ressourcen knapp –

+8

@Sam: Details;) Wahrheit in der Werbung: Ich würde ** nie ** in meiner Datenbank ausschalten. Die Lösung besteht immer darin, das Schema und die Abfragen richtig zu entwerfen, so dass Scans (die für die Eskalation verantwortlich sind) nicht vorkommen, um mit ... –

+0

völlig zustimmen ... es ist so selten, diese Art von Hacks und dann zu brauchen Am Ende beißt Sie sowieso –

Verwandte Themen