Sunting: Seperti @MaxVernon tunjukkan, berikut ini sama sekali bukan saran untuk menggunakan NOLOCK , dan saya sangat baik hanya menyebutkan pengaturan tingkat transaksi READ UNCOMMITEDdan membiarkan konotasi negatif berdiri di sana daripada membawa NOLOCKdi tempat pertama. Jadi seperti yang awalnya diposting:
Cepat dan sederhana adalah "Ya, permintaan pertama akan memblokir permintaan kedua kecuali petunjuk indeks tertentu ditentukan ( NOLOCK , kadang-kadang disebut" membaca kotor ") atau tingkat isolasi transaksi permintaan kedua diatur keREAD UNCOMMITED (yang beroperasi secara identik), tidak."
Menanggapi perincian tambahan yang disediakan dalam pertanyaan yang melibatkan dimasukkannya WITHklausa pada klausa yang kedua SELECT, saling eksklusif atau sebaliknya, interaksi antara kedua pertanyaan akan sebagian besar sama.
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;
Dalam sesi terpisah, jalankan yang berikut:
SELECT *
FROM dbo.Foo WITH ( NOLOCK );
GO
SELECT *
FROM dbo.Foo;
Anda dapat memeriksa kunci yang saat ini ditahan dengan berlari sp_lock, lebih disukai dalam sesi lain yang terpisah:
EXECUTE dbo.sp_lock;
Anda akan melihat KEYkunci jenis dipegang oleh spid yang melakukan transaksi penyisipan dalam Xmode (eksklusif), jangan dikacaukan dengan IXkunci (Intent-Eksklusif) lainnya. The kunci dokumentasi menunjukkan bahwa sementara KEYkunci adalah rentang tertentu, juga mencegah transaksi lainnya dari memasukkan atau memperbarui kolom yang terkena dengan mengubah data di dalamnya sehingga bisa jatuh dalam rentang dari query asli. Sebagai kunci itu sendiri ditahan adalah eksklusif, pertanyaan pertama adalah mencegah akses ke sumber daya dari setiap transaksi konkuren lainnya. Akibatnya, semua baris kolom dikunci, apakah mereka termasuk dalam rentang yang ditentukan oleh kueri pertama atau tidak.
The Skunci yang dipegang oleh sesi kedua akan demikian WAITsampai XClears kunci, mencegah lainX (atau U) kunci dari yang diambil pada sumber daya yang dari spid bersamaan berbeda sebelum sesi kedua selesai operasi baca nya, membenarkan keberadaan Skunci.
Sekarang edit untuk kejelasan: Kecuali saya salah dalam membaca kotor dari deskripsi singkat tentang risiko yang disebutkan di sini ... Edit 3 : Saya baru sadar saya tidak mempertimbangkan efek dari pos pemeriksaan latar belakang yang menulis sebagai transaksi belum berkomitmen ke disk, jadi ya, penjelasan saya menyesatkan.
Dalam kueri kedua, kumpulan pertama dapat (dan dalam hal ini, akan) mengembalikan data yang tidak dikomit. Batch kedua, berjalan di tingkat isolasi transaksi default READ COMMITEDakan kembali hanya setelah komit atau rollback telah selesai di sesi pertama.
Dari sini Anda dapat melihat rencana kueri Anda dan tingkat kunci terkait, tetapi lebih baik lagi, Anda dapat membaca semua tentang kunci di SQL Server di sini .
SELECT * FROM Table1jika itu yang saya butuhkan?