Düzenleme: @ @ MaxVernon işaret ettiği gibi , aşağıdaki hiçbir şekilde NOLOCK kullanmak için bir öneri değildir ve ben çok iyi sadece işlem düzeyini ayarlamak READ UNCOMMITED
ve negatif çağrışım getirmek daha orada durmasına izin bahsetmeliydimNOLOCK
ve ilk etapta . Başlangıçta yayınlandığı gibi:
Hızlı ve basit "Evet, ilk sorgu, belirli bir dizin ipucu belirtilmediğinde ( NOLOCK , bazen" kirli okuma "olarak adlandırılır) veya ikinci sorgunun işlem yalıtım düzeyi READ UNCOMMITED
(aynı şekilde çalışır) olarak ayarlanmadığı sürece ikinci sorguyu engeller , hayır, öyle değil. "
Karşılık olarak münhasır veya başka bir şekilde WITH
ikinci maddeye bir maddenin dahil edilmesini içeren soruda verilen ek ayrıntıya yanıt olarak, SELECT
iki sorgu arasındaki etkileşimler büyük ölçüde aynı olacaktır.
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'Foo'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.Foo;
CREATE TABLE dbo.Foo
(
Foo_PK BIGINT IDENTITY( 1, 1 ) NOT NULL,
PRIMARY KEY ( Foo_PK ),
Bar BIT,
x BIT,
y BIT,
z BIT
);
CREATE NONCLUSTERED INDEX IX_Foo_x
ON dbo.Foo ( x );
INSERT INTO dbo.Foo ( Bar, x, y, z )
VALUES ( 1, 1, 1, 1 ), ( 0, 0, 0, 0 );
END;
GO
BEGIN TRANSACTION;
UPDATE dbo.Foo
SET y = 0
WHERE x = 1;
-- COMMIT TRANSACTION;
Ayrı bir oturumda aşağıdakileri çalıştırın:
SELECT *
FROM dbo.Foo WITH ( NOLOCK );
GO
SELECT *
FROM dbo.Foo;
Şu anda tutulan kilitleri sp_lock
, tercihen başka bir ayrı oturumda çalıştırarak inceleyebilirsiniz :
EXECUTE dbo.sp_lock;
KEY
Ekleme işlemini gerçekleştiren örümcek tarafından X
(özel) modda tutulan , diğer IX
(Intent-Exclusive) kilitlerle karıştırılmaması gereken bir tür kilit görmeniz gerekir . Kilit belgeleri ise gösterir KEY
kilit menzil-özgü, aynı zamanda, içinde bu nedenle, orijinal sorgu bu aralık içinde düşebilir ihtiva sokulması veya veri değiştirilmesiyle etkilenen sütun güncelleme diğer işlemleri önler. Tutuluyor kilidi kendisi özeldir gibi, ilk sorgu gelen kaynağa erişim engelliyor herhangi başka eşzamanlı işlem. Aslında, ilk sorgu tarafından belirtilen aralığa dahil olsun ya da olmasın, sütunun tüm satırları kilitlenir.
Böylece S
ikinci oturum tarafından tutulan kilit WAIT
, X
kilit temizlenene kadar , ikinci oturum okuma işlemini tamamlamadan başka bir X
(veya U
) kilidin bu kaynak üzerinde farklı bir eşzamanlı hızdan alınmasını önleyerek kilidin varlığını haklı çıkarır S
.
Şimdi netlik için bir düzenleme: Burada belirtilen risklerin kısa açıklamasından kirli bir okunan şeyde yanlış olmadıkça ... Düzen 3 : Bir fark yazan bir arka plan kontrol noktasının etkisini düşünmediğimi fark ettim diske henüz taahhüt edilmemiş işlem, bu yüzden evet, benim açıklama yanıltıcı oldu.
İkinci sorguda, ilk toplu iş taahhüt edilmemiş verileri döndürebilir (ve bu durumda). Varsayılan işlem yalıtım düzeyinde çalışan ikinci toplu iş READ COMMITED
yalnızca ilk oturumda bir kesinleştirme veya geri alma işlemi tamamlandıktan sonra geri döner.
Buradan kendi sorgu planları ve ilgili kilit seviyelerinde bakabilirsiniz, ama daha iyisi, SQL Server kilitleri hakkında tüm okuyabilirsiniz burada .
SELECT * FROM Table1
Tam olarak ihtiyacım olan şey bu ise nasıl kötü bir uygulama ?