Sunting: Seperti @MaxVernon tunjukkan, berikut ini sama sekali bukan saran untuk menggunakan NOLOCK , dan saya sangat baik hanya menyebutkan pengaturan tingkat transaksi READ UNCOMMITED
dan membiarkan konotasi negatif berdiri di sana daripada membawa NOLOCK
di 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 WITH
klausa 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 KEY
kunci jenis dipegang oleh spid yang melakukan transaksi penyisipan dalam X
mode (eksklusif), jangan dikacaukan dengan IX
kunci (Intent-Eksklusif) lainnya. The kunci dokumentasi menunjukkan bahwa sementara KEY
kunci 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 S
kunci yang dipegang oleh sesi kedua akan demikian WAIT
sampai X
Clears 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 S
kunci.
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 COMMITED
akan 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 Table1
jika itu yang saya butuhkan?