Kilit türleri
| Kilit | Ne zaman? |
|---|---|
| Paylaşımlı (S) | Okurken; diğer okuyucularla uyumlu |
| Özel (X) | Yazarken; hiçbir kilitle uyumlu değil |
| Güncelleme (U) | Güncellemeden önce okurken; kilitlenmeyi önler |
SQL Server'ın varsayılan izolasyonu READ COMMITTED'dır ve klasik kilitleme kullanır: bir işlem satırı güncellerken o satırı okumak isteyen sorgu bekler (blocking).
NOLOCK neden tehlikeli?
SELECT COUNT(*) AS siparis FROM orders WITH (NOLOCK) WHERE status = 'delivered';
WITH (NOLOCK) (= READ UNCOMMITTED) beklemeyi önler ama kirli okuma yapar: onaylanmamış veri, aynı satırı iki kez okuma veya hiç okumama mümkündür. Finansal raporlarda kullanılmamalıdır.
Doğru çözüm: satır sürümleme
- READ_COMMITTED_SNAPSHOT (RCSI): Veritabanı düzeyinde açılır (
ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON). Okuyucular, yazarları beklemeden son onaylanmış sürümü okur. Azure SQL'de varsayılandır. - SNAPSHOT:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT; işlem boyunca tutarlı bir anlık görüntü.
system_health Extended Events oturumu deadlock kayıtlarını tutar; XML kaydını SSMS'te açınca süreçler ve kaynaklar çizilir. Okurken sor: kurban kim, hangi iki nesneye ters sırayla erişildi? Çözüm çoğunlukla nesnelere aynı sırayla erişmek ve işlemi kısaltmaktır.
SELECT CAST(event_data AS XML) AS olay
FROM sys.fn_xe_file_target_read_file('system_health*.xel', NULL, NULL, NULL)
WHERE object_name = 'xml_deadlock_report';Deadlock
İki işlem birbirinin tuttuğu kaynağı beklerse SQL Server birini kurban seçip Msg 1205 hatasıyla geri alır. Önlem: tablolara hep aynı sırayla eriş, işlemleri kısa tut, uygun indeksler kullan, uygulamada 1205 için yeniden deneme ekle.