Misalkan saya memiliki permintaan yang sudah berjalan lama berikut
UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows
dan misalkan kueri berikut dijalankan ketika kueri di atas sedang berjalan
SELECT *
FROM [Table1]
Apakah kueri pertama mencegah kueri kedua agar tidak berjalan hingga kueri pertama selesai? Jika demikian, apakah kueri pertama mencegah kueri kedua dari berjalan di semua baris atau hanya baris yang terlibat dalam klausa WHERE?
EDIT:
Misalkan permintaan kedua adalah
SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
-- the clause in the first query and which has additional matching elements
sumber
SELECT * FROM Table1
jika itu yang saya butuhkan?*
sendiri adalah praktik yang buruk karena ketika struktur tabel berubah aplikasi biasanya rusak (kolom yang tidak terduga muncul sebagai hasilnya).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 membawaNOLOCK
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 ke
READ UNCOMMITED
(yang beroperasi secara identik), tidak."Menanggapi perincian tambahan yang disediakan dalam pertanyaan yang melibatkan dimasukkannya
WITH
klausa pada klausa yang keduaSELECT
, saling eksklusif atau sebaliknya, interaksi antara kedua pertanyaan akan sebagian besar sama.Dalam sesi terpisah, jalankan yang berikut:
Anda dapat memeriksa kunci yang saat ini ditahan dengan berlari
sp_lock
, lebih disukai dalam sesi lain yang terpisah:Anda akan melihat
KEY
kunci jenis dipegang oleh spid yang melakukan transaksi penyisipan dalamX
mode (eksklusif), jangan dikacaukan denganIX
kunci (Intent-Eksklusif) lainnya. The kunci dokumentasi menunjukkan bahwa sementaraKEY
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 demikianWAIT
sampaiX
Clears kunci, mencegah lainX
(atauU
) kunci dari yang diambil pada sumber daya yang dari spid bersamaan berbeda sebelum sesi kedua selesai operasi baca nya, membenarkan keberadaanS
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 .
sumber
WITH (NOLOCK)
akan membantu dalam kasus ini. Lihat brentozar.com/archive/2011/11/… dan brentozar.com/archive/2013/02/… untuk bacaan lebih lanjut.WITH (NOLOCK)
petunjuknya tidak mengembalikan halaman kotor dari memori yang belum dilakukan. Ini benar-benar membaca baris dari tabel (baik di-disk atau cache di-memori) tanpa menghalangi penulis dari memperbarui atau menambahkan baris ke halaman yang digunakan oleh tabel.