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

Mengapa memasukkan blok pernyataan TSQL ketika tingkat isolasi transaksi untuk transaksi lain dapat diserialisasikan dengan filter yang tidak bertentangan?

Masalah pertama dalam skenario pengujian Anda adalah bahwa tabel tidak memiliki indeks yang berguna pada firstname . Yang kedua adalah mejanya kosong.

Dari Penguncian Rentang Kunci dalam BOL

Tidak ada indeks yang cocok untuk mengambil RangeS-S mengunci sehingga untuk menjamin semantik serial, SQL Server perlu mengunci seluruh tabel.

Jika Anda mencoba menambahkan indeks berkerumun pada tabel di kolom nama depan seperti di bawah ini dan ulangi percobaan ...

CREATE CLUSTERED INDEX [IX_FirstName] ON [dbo].[dummy] ([firstname] ASC)

... Anda akan menemukan bahwa Anda masih diblokir!

Terlepas dari kenyataan bahwa indeks yang sesuai sekarang ada dan rencana eksekusi menunjukkan bahwa indeks tersebut dicari untuk memenuhi kueri.

Anda dapat mengetahui alasannya dengan menjalankan yang berikut

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN

SELECT *
FROM   dummy
WHERE  firstname = 'abc'

SELECT resource_type,
       resource_description, 
       request_mode
FROM   sys.dm_tran_locks
WHERE  request_session_id = @@SPID

COMMIT 

Kembali

+---------------+----------------------+--------------+
| resource_type | resource_description | request_mode |
+---------------+----------------------+--------------+
| DATABASE      |                      | S            |
| OBJECT        |                      | IS           |
| PAGE          | 1:198                | IS           |
| KEY           | (ffffffffffff)       | RangeS-S     |
+---------------+----------------------+--------------+

SQL Server tidak hanya mengeluarkan kunci rentang tepat pada rentang yang Anda tentukan dalam kueri Anda.

Untuk predikat kesetaraan pada indeks unik jika ada kunci yang cocok, itu hanya akan mengambil kunci biasa daripada semua jenis kunci rentang sama sekali.

Untuk predikat pencarian yang tidak unik, ia mengeluarkan kunci pada semua kunci yang cocok dalam rentang ditambah yang "berikutnya" di akhir rentang (atau pada ffffffffffff untuk mewakili tak terhingga jika tidak ada kunci "berikutnya"). Bahkan catatan "hantu" yang dihapus dapat digunakan dalam penguncian tombol rentang ini.

Seperti yang dijelaskan di sini untuk predikat kesetaraan pada indeks unik atau tidak unik

Jadi dengan tabel kosong SELECT masih berakhir mengunci seluruh indeks. Anda juga harus menyisipkan baris sebelumnya di antara abc dan lmn dan kemudian penyisipan Anda akan berhasil.

insert into dummy values('def', 'def')


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. cara menghubungkan sql server menggunakan driver JTDS di Android

  2. SQL Server - Hubungan Pendek Permintaan?

  3. SQL Pivot dengan banyak kolom

  4. Bagaimana saya bisa memotong datetime di SQL Server?

  5. Urutan baris default dalam kueri SELECT - SQL Server 2008 vs SQL 2012