Jika saya membuat satu panggilan ke database SQL Server melalui jaringan latensi tinggi, akankah kunci tabel terjadi karena latensi itu? Katakanlah saya kueri tabel A untuk beberapa catatan, dan SQL Server harus mengembalikan data itu melalui jaringan lambat - apakah akan ada kunci baca di tabel A saat server mengirim respons melalui jaringan, atau apakah SQL Server melepaskan kunci sebelum mengirim responnya?
Juga, apakah jawabannya bervariasi berdasarkan pada ukuran respons? Jika itu hanya harus mengembalikan beberapa KB vs beberapa ratus MB, apakah itu akan membuat perbedaan?
Membuat transaksi eksplisit, menjalankan kueri, dan menutup transaksi jelas akan menyebabkan tabel terkunci, karena durasi transaksi berkorelasi dengan latensi saya.
sumber
nolock
petunjuk, akan selalu ada kunci . Latensi hanya menentukan berapa lama kunci akan ditahan.nolock
, Anda masih akan mendapatkan kunciUnless you specify a nolock hint, there will always be a lock.
<- ini menyiratkan jika Anda menggunakan nolock mungkin tidak ada kunci. Saya hanya mengklarifikasi.Jawaban:
Ini tidak akurat, itu tergantung pada tingkat isolasi.
Pada awalnya
READ COMMITTED
kunci tidak ditahan selama durasi eksekusi pernyataan.READ COMMITTED
tidak memberikan konsistensi tingkat pembacaan pernyataan, satu-satunya jaminan adalah bahwa Anda tidak dapat membaca data yang tidak dikomit. Kunci bersama diperoleh dan ditahan untuk membaca baris dan kemudian dilepaskan.Kecuali Anda memiliki tipe LOB.
Jenis LOB, karena berpotensi sangat besar, tidak dapat disangga. Kunci yang dibagikan harus diperoleh dan ditahan sampai pernyataan selesai, pada dasarnya memberi Anda
REPEATABLE READ
perilaku diREAD COMMITTED
.Latensi tidak menyebabkan kunci tabel, tidak. Namun, jika kunci meja telah diperoleh, latensi akan memperpanjangnya.
Mengutip seseorang yang tahu mekanisme ini lebih baik dari saya ( @RemusRusanu ):
Di mana hasil tidak dikonsumsi secepat SQL Server dapat mengirimkannya, baik itu karena klien atau jaringan, kami melihat
ASYNC_NETWORK_IO
menunggu akumulasi. Untuk mengulangi, ini tidak akan mempengaruhi kunci yang diperoleh, hanya durasi mereka ditahan.sumber
Jawaban Mark menghilangkan banyak kebingungan saya, tetapi saya ingin memposting temuan saya setelah saya menguji ini menggunakan NetBalancer untuk meniru latensi.
Saya meminta mesin lokal saya memanggil server SQL jarak jauh dan menjalankan SELECT dan INSERT di atas meja dalam transaksi kecil. Pada mesin jarak jauh, saya terhubung ke instance SQL lokal dan menggunakan loop WHILE untuk berulang kali beralih ke tabel sys.dm_tran_locks, mencari kunci apa saja di meja yang saya modifikasi dan baca. Saya menginstal NetBalancer di server dan menggunakannya untuk meniru latensi jaringan pada koneksi jaringan server.
Inilah yang saya temukan:
Dari ini, saya menyimpulkan bahwa latensi tidak masalah asalkan data sesuai dengan buffer jaringan. Jika SQL harus meletakkan banyak data dalam buffer jaringan, latensi akan membuat buffer itu untuk membuat cadangan dan SQL akan menahan kunci tabel sampai dapat menempatkan semua hasil permintaan ke buffer.
sumber
Ketika kueri dipecat dan diselesaikan oleh SQL Server menghasilkan hasil, letakkan di buffer output dan kirim ke klien yang kemudian mengambil hasil dari buffer Output. SQL Server tidak akan melepaskan kunci yang dipegang oleh permintaan kecuali Pengakuan diterima dari Klien. Yang mungkin menyebabkan pemblokiran.
Sunting: Evan Anda bisa merujuk ke artikel dukungan MS ini
Di bagian 3
Memblokir yang Disebabkan oleh SPID yang Aplikasi Kliennya Sesuai Tidak Menjemput Semua Baris Hasil untuk Diselesaikan
Setelah mengirim kueri ke server, semua aplikasi harus segera mengambil semua baris hasil sampai selesai. Jika suatu aplikasi tidak mengambil semua baris hasil, kunci dapat dibiarkan di atas meja, memblokir pengguna lain. Jika Anda menggunakan aplikasi yang secara transparan mengirimkan pernyataan SQL ke server, aplikasi harus mengambil semua baris hasil. Jika tidak (dan jika tidak dapat dikonfigurasi untuk melakukannya), Anda mungkin tidak dapat menyelesaikan masalah pemblokiran. Untuk menghindari masalah, Anda dapat membatasi aplikasi yang berperilaku buruk ke pelaporan atau database pendukung keputusan.
sumber
SELECT *
dari dalam diREAD COMMITTED
dalam satu koneksi SSMS, monitor mengunci dari yang lain. Kapan saja, berapa banyak kunci yang Anda lihat dipegang?