SQL Server Error 1222: Kilit Zaman Aşımı — Kim Kilitliyor?
1222 ile 1205 ve client timeout arasındaki fark, blokaj zincirinin başını bulma sorgusu ve NOLOCK yerine doğru çözüm.
Hata mesajı semptomdur, kök neden değildir. Sunucuyu yeniden başlatmadan veya rastgele ayar değiştirmeden önce aşağıdaki "Nedeni ayırt eden tek sorgu"yu çalıştırarak gerçek senaryoyu netleştirin.
▸Belirti
Lock request time out period exceeded.Üç farklı zaman aşımı birbiriyle karıştırılır; ayrımı yapmak işin yarısıdır:
| Hata | Kim üretir | Anlamı |
|---|---|---|
1222 | Sunucu | LOCK_TIMEOUT süresi doldu, kilit alınamadı |
1205 | Sunucu | Deadlock — döngüsel kilitlenme var, kurban seçildi |
Execution Timeout Expired | İstemci | Sorgu çalışıyordu ama istemci zaman aşımı süresi bitti |
1222'de döngü yoktur; sadece bir işlem diğerini beklemekten vazgeçmiştir. SQL Server'da varsayılan LOCK_TIMEOUT sınırsızdır (-1). Yani bu hatayı görüyorsanız bir yerlerde süre ayarlanmıştır — genellikle ORM veya bağlantı katmanı:
SELECT @@LOCK_TIMEOUT; -- -1 ise sınırsız▸Blokaj zincirinin başını bulma
Kritik kural: şikayet eden değil, zincirin başındaki oturum sorumludur.
SELECT r.session_id,
r.blocking_session_id,
r.wait_type,
r.wait_time / 1000 AS bekleme_sn,
r.wait_resource,
SUBSTRING(t.text, 1, 200) AS sorgu
FROM sys.dm_exec_requests r
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.blocking_session_id <> 0
ORDER BY r.wait_time DESC;Zincirin başındaki oturumu (blocking_session_id = 0 olan ve başkalarını bekleten) tespit edin:
SELECT s.session_id, s.login_name, s.host_name, s.program_name,
s.status, s.last_request_start_time, s.open_transaction_count
FROM sys.dm_exec_sessions s
WHERE s.session_id = 87; -- baş bloklayıcı oturum IDstatus = 'sleeping' ve open_transaction_count > 0 ise tanı kesindir: uygulama BEGIN TRAN açmış, işi bitmiş ama COMMIT etmemiştir.
▸Çözüm adımları
1. Baş bloklayıcıyı sonlandırın.
KILL 87;KILL öncesi oturumun ne yaptığını doğrulayın; yarıda kesilen büyük bir yazma işlemi uzun bir rollback başlatabilir.
2. `NOLOCK` ile "çözmeyin". Uygulamaya rastgele WITH (NOLOCK) eklemek blokajı gizler ama yanlış sonuç üretir: okunmamış (kirli) satırlar, iki kez sayılan satırlar, eksik dönen kayıtlar. Raporlarda "sayılar tutmuyor" şikayetinin kaynağı budur. Doğru çözüm satır sürümleme (RCSI) açmaktır:
ALTER DATABASE uygulama_db SET READ_COMMITTED_SNAPSHOT ON;Bu ayar, okuyucuların yazıcıları bloklamasını engeller ve NOLOCK'ın yarattığı veri tutarsızlıklarını üretmez.
3. Şema kilitlerini ayrı değerlendirin. wait_resource değeri METADATA içeriyorsa blokaj satır değil nesne seviyesindedir (ALTER TABLE, TRUNCATE veya istatistik güncellemesi). Bu durumda READ_COMMITTED_SNAPSHOT tek başına yardımcı olmaz.
4. İşlemleri kısaltın. Uygulama kuralı: Transaction içinde asla kullanıcı girdisi beklenmez, HTTP/REST API çağrısı yapılmaz, dosya okunmaz.
▸Bunu bir daha yaşamamak için
sys.dm_exec_requests üzerinden 5 saniyeden uzun bekleyen istek sayısını izleme metriği yapın. Uygulama tarafında LOCK_TIMEOUT'u bilinçli ayarlayın (5–10 saniye çoğu OLTP iş yükü için idealdir).
- •İlgili Hata: SQL Server Error 1205: Deadlock Victim
- •İlgili Hata: SQL Server Connection Pool Timeout
Diğer Veritabanı Hata Teşhisleri
Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.
PostgreSQL too many clients already Hatası: 6 Adımda Çözüm
FATAL: sorry, too many clients already hatasının üç nedeni, nedeni ayırt eden tek sorgu ve max_connections ile PgBouncer üzerinden kalıcı çözümü.
PostgreSQL password authentication failed Hatası: Neden ve Çözüm
psql password authentication failed hatasının dört nedeni: yanlış şifre, md5/SCRAM uyuşmazlığı, pg_hba.conf sırası ve yanlış cluster. Adım adım teşhis.
MySQL ERROR 1045 Access denied: root Şifresi Sıfırlama Rehberi
MySQL 1045 hatasının dört nedeni, "using password: YES/NO" ayrımının anlamı ve kilitli kalınca --init-file ile güvenli şifre sıfırlama.