MSSQL Server’da Key-Range Locking, özellikle “Serializable” izolasyon seviyesinde karşımıza çıkan, hayalet okumaları (phantom reads) engellemek için kullanılan gelişmiş bir kilitleme mekanizmasıdır.
Basitçe söylemek gerekirse; sadece var olan satırları değil, o satırların arasındaki boşlukları (range) da kilitler.
Key-Range Lock Türleri
SQL Server bu kilidi iki bileşenle ifade eder: Aralık Kilidi (Range) ve Satır Kilidi (Key). En yaygın formatlar şunlardır:
- RangeS-S: Aralığı ve satırı paylaşımlı (shared) olarak kilitler. Kimse veri ekleyemez veya güncelleyemez.
- RangeS-U: Aralığı paylaşımlı kilitler ama satırı güncelleme (update) için rezerve eder.
- RangeI-N (Insert Range): Yeni bir satır eklenirken, eklenecek yerin boş olduğunu garantilemek için kullanılır.
SELECT * FROM Orders WHERE OrderDate BETWEEN '2024-01-01' AND '2024-12-31'
Yukarıdaki sorguda WHERE OrderDate BETWEEN ‘2024-01-01’ AND ‘2024-12-31’ sorgusunu Serializable seviyesinde çalıştırdığınızda:
- Satır Kilidi: ‘2024-01-01’ ve ‘2024-12-31’ değerlerine sahip satırlar kilitlenir.
- Aralık Kilidi: ‘2024-01-01’ ve ‘2024-12-31’ arasındaki tüm hayali boşluklar kilitlenir.
- Sonuç: Başka bir kullanıcı bu tarih aralıklarında herhangi bir değeri sorgulayamaz.
Temel Özellikler
| Özellik | Açıklama |
| İzolasyon Seviyesi | Yalnızca SERIALIZABLE seviyesinde tetiklenir. |
| Gereksinim | Sorgulanan sütunda mutlaka bir Index (indeks) bulunmalıdır. |
| Hedef | Insert, Update ve Delete operasyonlarının araya sızmasını önlemek. |
Sisteminizde aktif olan Key-Range kilitlerini görmek için şu DMV’yi (Dynamic Management View) kullanabilirsiniz:
SELECT resource_type, request_mode, resource_description
FROM sys.dm_tran_locks
WHERE resource_type = 'KEY';
Bu mekanizma veri tutarlılığı için harikadır ancak çok fazla kullanıldığında deadlock (ölümcül kilitlenme) riskini artırabilir.
Aşağıdaki komut sayesinde anlık gelen sorgularımızdaki kilit durumlarını görebiliriz.
SELECT
session_id AS SessionID,
blocking_session_id AS BlockingSessionID,
wait_type AS WaitType,
wait_time AS WaitTime,
wait_resource AS WaitResource
FROM
sys.dm_exec_requests
WHERE
blocking_session_id > 0;

Bir başka komut ise:

Sp_whoIsactive ekranındada ilgili kilitlenmeleri görebiliriz.

Veritabanımızın üzerindeki lock’ları aşağıdaki uzantıda görebiliriz.

Başka bir makalede görüşmek dileğiyle..
