2010-12-29 5 views
1

Ich habe folgendes SP:SQL Server: serializable Ebene nicht funktioniert

CREATE PROCEDURE [dbo].[sp_LockReader] 
AS 
BEGIN 
SET NOCOUNT ON; 
begin try 
set transaction isolation level serializable 
begin tran 
select * from teste 
commit tran 
end try 
begin catch 
rollback tran 
set transaction isolation level READ COMMITTED 
end catch 
set transaction isolation level READ COMMITTED 
END 

Die Tabelle "Test" viele Werte hat, so "select * from teste" mehrere Sekunden dauert. Ich führe den sp_LockReader gleichzeitig in zwei verschiedenen Abfragefenstern aus und der zweite zeigt den Inhalt der Testtabelle an, ohne dass der erste beendet wird.

  • Sollte die serializable-Ebene die zweite Abfrage nicht warten?
  • Wie bekomme ich das beschriebene Verhalten?

Dank

Antwort

3

SERIALIZABLE an den einfachsten Mitteln "halten Schlösser für länger". Wenn Sie SELECT wählen, handelt es sich bei der gehaltenen Sperre um eine gemeinsame Sperre, die anderen Lesern erlaubt.

Wenn Sie Leser blockieren möchten, verwenden Sie WITH (TABLOCKX) Hinweis, um eine exklusive Sperre zu nehmen, wo Sie SERIALIZABLE nicht benötigen. Oder XLOCK mit SERIALIZABLE

Mit anderen Worten:

  • SERIALIZABLE = Isolation Level = Sperre Dauer, Gleichzeitigkeit
  • XLOCK = mode = Sharing/Exklusivität
  • TABLOCK = Granularität = was gesperrt ist

  • TABLOCKX = kombiniert

See this question/answer for more info

1

Eine serialisierbare Transaktion, deren Ausgabe nicht durch andere gleichzeitige Transaktionen beeinflusst wird. In Ihrem Fall wählen Sie zweimal aus der Tabelle SELECT; Keine dieser Transaktionen ändert die Ergebnismenge der anderen, sodass beide gleichzeitig ausgeführt werden können.

Auch wenn eine Transaktion die Tabelle aktualisiert hat, würde dies die Ausführung des anderen nicht unbedingt verhindern, da die Datenbank möglicherweise aus Snapshots funktioniert.

Werfen Sie einen Blick hier für eine bessere Erklärung als ich biete ... kann hier http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

0

Noch ein Hinweis. Wenn Sie XLOCK unter einer SERIALIZABLE-Isolation verwenden, können andere Transaktionen mit READ COMMITTED-Isolation weiterhin XLOCK'ed-Zeilen lesen.

Um dies zu verhindern, verwenden Sie PAGLOCK zusammen mit XLOCK. http://support.microsoft.com/kb/324417

+0

Der KB-Artikel scheint nur für SQL Server 2000 gelten. Ich bin ziemlich sicher, dass die meisten Menschen auf mindestens 2005 aktualisiert haben. –

+1

Ja Jordan, du hast Recht. Es blockiert erfolgreich eine READ COMMITTED-Transaktion. Ich habe es mit 2008 R2 getestet. Lesezugriff wurde (in anderen Fällen) in zwei Szenarien gewährt, wenn die Zeilen XLOCK'ed waren - 1) auf einem READ UNCOMMITTED & 2) auf einem SNAPSHOT. Ein SNAPSHOT mit einem XLOCK wurde jedoch blockiert. – Srinidhi

Verwandte Themen