"Transaction was deadlocked" hatası mı alıyorsunuz? Deadlock'un ne olduğunu, nasıl tespit edileceğini ve kalıcı çözüm için uygulanması gereken desenleri örneklerle anlatıyoruz.
SQL Server'da ara sıra karşılaşılan "Transaction (Process ID) was deadlocked" (hata 1205) mesajı, iki işlemin birbirinin kilidini beklerken kilitlenmesinden kaynaklanır. İyi haber: neden ve çözümü genellikle bellidir.
Deadlock nedir?
İki işlem düşünün: A işlemi X kaydını kilitler ve Y'yi bekler; B işlemi Y'yi kilitler ve X'i bekler. İkisi de diğerinin bırakmasını beklediği için sonsuza dek takılırlar. SQL Server bunu algılar ve daha az maliyetli olan işlemi "kurban" seçip geri alır (rollback).
Nasıl tespit edilir?
- Extended Events içindeki
xml_deadlock_reportile deadlock grafiğini yakalayın — hangi sorguların ve kaynakların çatıştığını gösterir. - Sistem sağlığı oturumu (
system_health) çoğu deadlock'ı zaten kaydeder. - Deadlock grafiğinde kurban işlemi ve tutulan/beklenen kilitleri okuyarak kök nedeni bulun.
Yaygın nedenler
- Tabloların farklı işlemlerde farklı sırayla güncellenmesi.
- Uzun süren transaction'lar ve kullanıcı etkileşimini transaction içinde bekletmek.
- Eksik indeksler yüzünden geniş tarama ve gereğinden fazla satırın kilitlenmesi.
Nasıl çözülür?
- Tablolara her zaman aynı sırayla erişin; tutarlı sıra deadlock'ların büyük kısmını yok eder.
- Transaction'ları kısa tutun; içine ağ/kullanıcı beklemesi koymayın.
- Doğru indeksleri ekleyerek kilitlenen satır sayısını azaltın.
- Okuma çakışmalarını azaltmak için Read Committed Snapshot (RCSI) yalıtım düzeyini değerlendirin.
- Yine de olabileceğini varsayıp uygulamada 1205 için yeniden deneme (retry) mantığı ekleyin.
Özet
Deadlock'ları tamamen yok etmek her zaman mümkün olmasa da, tutarlı erişim sırası + kısa transaction + doğru indeksler çoğunu ortadan kaldırır. Kalanı için de zarif bir yeniden deneme mantığı, kullanıcının hiç fark etmemesini sağlar.