2016-02-29 26 views
5

platziert wird Ich glaube, dass jede SELECT Anweisung in SQL Server wird entweder eine Shared oder Key-Sperre platziert werden. Aber wird es die gleiche Art von Sperre platzieren, wenn es in einer Transaktion ist? Werden Shared- oder Key-Sperren anderen Prozessen erlauben, dieselben Datensätze zu lesen?Welche Art von Sperre für SELECT-Anweisung innerhalb einer Transaktion in SQL Server

Zum Beispiel habe ich die folgende Logik

Begin Trans 
-- select data that is needed for the next 2 statements 
SELECT * FROM table1 where id = 1000; -- Assuming this returns 10, 20, 30 

insert data that was read from the first query 
INSERT INTO table2 (a,b,c) VALUES(10, 20, 30); 

-- update table 3 with data found in the first query 
UPDATE table3 
SET d = 10, 
    e = 20, 
    f = 30; 

COMMIT; 

An diesem Punkt wird meine Select-Anweisung noch eine gemeinsame oder Tastensperre erstellen oder wird es exklusive Sperre eskaliert werden? Ist eine andere Transaktion in der Lage, Datensätze aus der Tabelle1 zu lesen, oder wartet die gesamte Transaktion, bis die my-Transaktion festgeschrieben wird, bevor andere sie auswählen können?

In einer Anwendung macht es seit dem Verschieben der Select-Anweisung außerhalb einer Transaktion und nur die Einfügung/Aktualisierung in einer Transaktion zu halten?

Antwort

7

A SELECT wird immer eine gemeinsame Sperre setzen - wenn Sie den WITH (NOLOCK) Hinweis (dann keine Sperre platziert werden) verwenden, verwenden Sie eine READ UNCOMMITTED Transaktionsisolationsstufe (gleiche), oder wenn Sie es speziell mit Abfragehinweise außer Kraft setzen wie WITH (XLOCK) oder WITH (UPDLOCK).

Eine gemeinsame Sperre ermöglicht es anderen Lesevorgängen, eine gemeinsame Sperre zu erhalten und die Daten zu lesen - sie verhindern jedoch, dass exklusive Sperren (für Einfüge-, Lösch- und Aktualisierungsvorgänge) erfasst werden.

In diesem Fall, mit nur drei Zeilen ausgewählt, gibt es keine Sperre Eskalation (das passiert nur, wenn mehr als 5000 Sperren durch eine einzige Transaktion erworben werden).

Abhängig von der Transaktionsisolationsstufe werden diese freigegebenen Sperren unterschiedlich lange gehalten. Mit READ COMMITTED, der Standardstufe, werden die Sperren sofort nach dem Lesen der Daten freigegeben, während die Sperren mit den Ebenen REPEATABLE READ oder SERIALIZABLE beibehalten werden, bis die Transaktion festgeschrieben oder zurückgesetzt wird.

+0

Vielen Dank für diese wertvollen Informationen. Wenn SQL Server standardmäßig "Read Committed" für eine SELECT-Anweisung verwendet. Seit dem Versuch, meine SELECT-Abfragen außerhalb der Transaktion zu trennen, gibt es nicht mehr –

+0

@MikeA: nein, macht keinen Unterschied - die gemeinsamen Sperren werden nur sehr kurz für das tatsächliche * Lesen * der Daten erworben (nur um einen anderen Prozess zu verhindern) Ändern sie, während Sie sie lesen), und dann werden sie wieder freigegeben werden - innerhalb oder außerhalb dieser Transaktion - gleichen Prozess –

+0

Wenn Sie nicht wissen: READ COMMITTED wählt nicht immer sperren. Sperren werden nur auf Seiten mit nicht festgeschriebenen Änderungen vorgenommen. Sie können eine Tabelle unter RC lesen, die von einer anderen Transaktion XLOCK, TABLOCK'ed wurde. (Ich habe das versucht.) – usr