Apakah ada cara untuk mencegah kebuntuan dengan tetap mempertahankan pertanyaan yang sama?
Grafik deadlock menunjukkan bahwa kebuntuan khusus ini adalah kebuntuan konversi yang terkait dengan pencarian bookmark (pencarian RID dalam kasus ini):
Sebagaimana dicatat oleh pertanyaan, risiko kebuntuan umum muncul karena permintaan dapat memperoleh kunci yang tidak kompatibel pada sumber daya yang sama dalam pesanan yang berbeda. The SELECT
permintaan kebutuhan untuk mengakses indeks sebelum meja karena lookup RID, sedangkan UPDATE
memodifikasi permintaan meja pertama, maka indeks.
Menghilangkan kebuntuan membutuhkan menghilangkan salah satu bahan kebuntuan. Berikut ini adalah opsi utama:
- Hindari pencarian RID dengan membuat penutup indeks nonclustered. Ini mungkin tidak praktis dalam kasus Anda karena
SELECT
kueri mengembalikan 26 kolom.
- Hindari pencarian RID dengan membuat indeks berkerumun. Ini akan melibatkan pembuatan indeks berkerumun di kolom
Proposal
. Ini patut dipertimbangkan, meskipun tampaknya kolom ini bertipe uniqueidentifier
, yang mungkin atau mungkin bukan pilihan yang baik untuk indeks berkerumun, tergantung pada masalah yang lebih luas.
- Hindari mengambil kunci bersama saat membaca dengan mengaktifkan opsi
READ_COMMITTED_SNAPSHOT
atau SNAPSHOT
basis data. Ini akan membutuhkan pengujian yang cermat, terutama sehubungan dengan perilaku memblokir yang dirancang-dalam. Kode pemicu juga akan memerlukan pengujian untuk memastikan logika berkinerja dengan benar.
- Hindari mengambil kunci bersama saat membaca dengan menggunakan
READ UNCOMMITTED
level isolasi untuk SELECT
kueri. Semua peringatan yang biasa berlaku.
- Hindari eksekusi bersamaan dari dua pertanyaan yang bersangkutan dengan menggunakan kunci aplikasi eksklusif (lihat sp_getapplock ).
- Gunakan petunjuk kunci meja untuk menghindari konkurensi. Ini adalah palu yang lebih besar dari opsi 5, karena dapat memengaruhi pertanyaan lain, bukan hanya dua yang diidentifikasi dalam pertanyaan.
Bisakah saya mengambil X-Lock pada indeks dalam transaksi pembaruan sebelum pembaruan untuk memastikan akses tabel dan indeks dalam urutan yang sama
Anda dapat mencoba ini, dengan membungkus pembaruan dalam transaksi eksplisit dan melakukan SELECT
dengan XLOCK
petunjuk pada nilai indeks yang tidak tercakup sebelum pembaruan. Ini bergantung pada Anda mengetahui dengan pasti berapa nilai saat ini dalam indeks nonclustered, menjalankan rencana eksekusi dengan benar, dan mengantisipasi dengan benar semua efek samping dari mengambil kunci tambahan ini. Itu juga bergantung pada mesin pengunci yang tidak cukup pintar untuk menghindari pengambilan kunci jika dinilai berlebihan .
Singkatnya, sementara ini pada prinsipnya layak, saya tidak merekomendasikannya. Terlalu mudah untuk melewatkan sesuatu, atau mengakali diri sendiri dengan cara-cara kreatif. Jika Anda benar-benar harus menghindari kebuntuan ini (bukan hanya mendeteksi dan mencoba lagi), saya akan mendorong Anda untuk mencari solusi yang lebih umum yang tercantum di atas.