Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Pertanyaan SQL Deadlock

SELECT tidak dapat menemui jalan buntu dengan SELECT lainnya, karena mereka hanya memperoleh kunci bersama. Anda mengatakan bahwa kami harus mempertimbangkan bahwa SELECT ini sekarang 'memerlukan kunci baca eksklusif', tetapi ini tidak mungkin untuk kami pertimbangkan karena 1) tidak ada yang namanya exlusive read lock dan 2) pembacaan tidak mendapatkan kunci eksklusif.

Tetapi Anda mengajukan pertanyaan yang lebih umum, apakah pernyataan sederhana dapat menemui jalan buntu. Jawabannya pasti, YA . Kunci diperoleh pada saat eksekusi, tidak dianalisis di muka dan diurutkan kemudian diperoleh dalam beberapa urutan. Tidak mungkin bagi mesin untuk mengetahui di muka kunci yang diperlukan karena mereka bergantung pada data aktual di dalam disk, dan untuk membaca data, mesin perlu ... mengunci data.

Kebuntuan antara pernyataan sederhana (SELECt vs. UPDATE atau SELECT vs. DELETE) karena urutan akses indeks yang berbeda cukup umum dan sangat mudah untuk diselidiki, didiagnosis, dan diperbaiki. Namun perhatikan bahwa selalu operasi tulis yang terlibat, karena pembacaan tidak dapat memblokir satu sama lain. Untuk diskusi ini, menambahkan petunjuk UPDLOCK atau XLOCK ke SELECT harus dianggap sebagai penulisan. Anda bahkan tidak perlu GABUNG, indeks sekunder mungkin memperkenalkan masalah urutan akses yang mengarah ke kebuntuan, lihat Baca/Tulis Deadlock .

Dan terakhir, tulis SELECT FROM A JOIN B atau tulis SELECT FROM B JOIN A sama sekali tidak relevan. Pengoptimal kueri bebas mengatur ulang urutan akses sesuai keinginan, teks kueri yang sebenarnya tidak memaksakan urutan eksekusi dengan cara apa pun.

Diperbarui

Saya khawatir tidak ada resep pemotong kue. Solusinya akan tergantung dari kasus ke kasus. Pada akhirnya, dalam aplikasi database kebuntuan adalah fakta kehidupan. Saya mengerti ini mungkin terdengar tidak masuk akal, seperti dalam 'kami mendarat di Bulan tetapi kami tidak dapat menulis aplikasi basis data yang benar', tetapi ada faktor kuat yang berperan yang cukup banyak menjamin bahwa aplikasi pada akhirnya akan menemui jalan buntu. Kebuntuan keberuntungan adalah yang termudah untuk menangani kesalahan, sederhana membaca lagi keadaan, menerapkan logika, menulis ulang keadaan baru. Sekarang dikatakan, ada beberapa praktik baik yang dapat secara dramatis mengurangi frekuensi kebuntuan, sampai-sampai semuanya hilang:

  • Cobalah untuk memiliki pola akses yang konsisten untuk Tulis . Memiliki aturan yang jelas menyatakan hal-hal seperti 'transaksi harus selalu tabel dalam urutan ini:Customers -> OrderHeaders -> OrderLines .' Perhatikan bahwa perintah harus dipatuhi di dalam transaksi . Pada dasarnya, beri peringkat semua tabel dalam skema Anda dan tentukan bahwa semua pembaruan harus terjadi dalam urutan peringkat. Hal ini pada akhirnya bermuara pada disiplin kode dari masing-masing kontributor yang menulis kode, karena kode tersebut harus memastikan bahwa penulisannya diperbarui dalam urutan yang benar dalam suatu transaksi.
  • Kurangi durasi dari menulis. Kebijaksanaan biasanya seperti ini:di awal transaksi lakukan semua pembacaan (baca status yang ada), lalu proses logika dan hitung nilai baru, lalu tulis semua pembaruan di akhir transaksi. Hindari pola seperti 'read->write->logic->read->write', alih-alih lakukan 'read->read->logic->write->write'. Tentu saja, keahlian yang sebenarnya terdiri dari bagaimana menangani kasus-kasus individual yang nyata dan nyata ketika tampaknya harus harus melakukan menulis pertengahan transaksi. Catatan khusus di sini harus dikatakan tentang jenis transaksi tertentu:transaksi yang didorong oleh antrian, yang menurut definisi memulai aktivitasnya dengan menghilangkan antrian (=menulis) dari antrian. Aplikasi ini selalu terkenal sulit untuk ditulis dan rentan terhadap kesalahan (khususnya kebuntuan), untungnya ada cara untuk melakukannya, lihat Menggunakan tabel sebagai Antrian .
  • Kurangi jumlah pembacaan. Pemindaian tabel adalah yang penyebab paling umum dari kebuntuan. Pengindeksan yang tepat tidak hanya akan menghilangkan kebuntuan, tetapi juga dapat meningkatkan kinerja dalam proses.
  • Isolasi snapshot . Ini adalah hal terdekat yang akan Anda dapatkan untuk makan siang gratis untuk menghindari kebuntuan. Saya sengaja menempatkannya terakhir, karena mungkin menutupi masalah lain (seperti pengindeksan yang tidak tepat) alih-alih memperbaikinya.

Mencoba memecahkan masalah ini dengan LockCustomerByXXX pendekatan yang saya khawatirkan tidak berhasil. Penguncian pesimis tidak berskala. Konkurensi yang optimis pembaruan adalah yang cara yang harus dilakukan jika Anda ingin memiliki performa yang layak.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bergabung dengan beberapa tabel mengembalikan nilai NULL

  2. Gunakan variabel dengan TOP dalam pernyataan pilih di SQL Server tanpa membuatnya dinamis

  3. Perbandingan Data SQL - Beberapa tabel hilang

  4. Buat Profil Publik Default untuk Database Mail di SQL Server (T-SQL)

  5. Menerapkan Indikator Kinerja MS SQL Server Umum