Apakah kueri pemilihan sederhana memperoleh kunci?

14

Saya sangat baru dalam SQL Server, dan ingin memahami apakah pernyataan berikut yang sangat sederhana ini selectakan mengambil kunci apa pun.

Select * from Student;

Harap perhatikan kasus di mana pernyataan tidak akan berjalan di dalam begin tranblok.

Pengembang Baru
sumber
1
Ini adalah pertanyaan yang jauh lebih rumit daripada yang mungkin Anda pikirkan. Jawabannya tergantung pada banyak hal (apa tingkat isolasi transaksi sesi? Dibaca dengan komitmen snapshot yang diaktifkan? Apakah indeks yang dipindai memiliki opsi yang diatur untuk mencegah baris atau kunci halaman?) Dan bahkan dapat berubah selama pernyataan berjalan (berapa banyak baris ada di dalam tabel? adalah tabel yang dipartisi?). Inilah poin yang baik untuk mulai membaca.
Jon Seigel

Jawaban:

5

Ya itu memang mengambil kunci bersama pada baris yang dibaca secara default (itu juga mengambil kunci Bersama Intent pada semua halaman indeks berkerumun yang akan dibaca), ini dilakukan untuk mencegah pembacaan kotor. Namun ada cara untuk memotong ini (SQL Server memiliki petunjuk nolock). Jika pernyataan tidak dalam BEGIN TRAN, kunci dilepaskan setelah pernyataan SELECT dijalankan.

Info lebih lanjut dapat ditemukan di sini:

http://msdn.microsoft.com/en-us/library/ms184286(v=sql.105).aspx http://www.sqlteam.com/article/introduction-to-locking-in-sql-server

Bebas keriput
sumber
Selain itu Anda juga dapat mengatur tingkat isolasi transaksi untuk membaca tanpa komitmen.
Zane
1
Jadi jika SELECT membaca sepuluh baris, apakah sepuluh kunci bersama dimiliki hingga semua sepuluh baris telah dibaca atau mereka diperoleh dan dirilis per baris?
Ian Warburton
26

Saya ingin memahami apakah pernyataan pilih berikut yang sangat sederhana ini akan mengambil kunci

Ini adalah kesalahpahaman umum bahwa SELECTpermintaan berjalan pada READ COMMITTEDtingkat isolasi transaksi default akan selalu mengambil kunci bersama untuk mencegah pembacaan kotor.

SQL Server dapat menghindari pengambilan kunci tingkat baris bersama ketika tidak ada bahaya membaca data yang tidak dikomit tanpa mereka (meskipun kunci Intent-Shared (IS) tingkat tinggi masih diambil).

Bahkan jika bersama baris kunci yang diambil (mungkin karena transaksi konkuren lain telah memodifikasi halaman baris adalah pada) mereka dapat dilepaskan jauh sebelum SELECTSelesaikan pernyataan.

Dalam kebanyakan kasus, baris 'tidak terkunci' tepat sebelum server memproses baris berikutnya. Ada keadaan di mana kunci bersama diambil pada tingkat isolasi default diadakan sampai akhir pernyataan saat ini, tetapi tidak sampai akhir transaksi .

Mengganti level isolasi saat ini dengan NOLOCKpetunjuk tabel hampir selalu merupakan ide yang buruk .

Mengunci adalah detail implementasi. SQL Server mengambil kunci ketika diperlukan untuk memastikan memenuhi jaminan semantik yang disediakan oleh tingkat isolasi saat ini . Memang ada saat-saat di mana berguna untuk mengetahui sedikit tentang mengapa kunci diambil, tetapi upaya untuk memperkirakannya sering kali tidak produktif.

SQL Server menyediakan berbagai tingkat isolasi; pilih salah satu yang memberikan jaminan dan perilaku data yang dibutuhkan konsumen.

Paul White 9
sumber