Merhaba Sevgili Veritabanı Tutkunları!
Bir sabah işe geldiğinizde, gözünüz o korkulu hata mesajına takıldı mı hiç: “Transaction Deadlock Detected”? Tam projeye dalmış, işler yolundayken, bir anda tüm işlemler tıkanıyor. Panik yapmayın! Bu yazıda, bu sinir bozucu hatanın nedenlerini, nasıl tespit edileceğini ve en önemlisi, nasıl çözüleceğini adım adım anlatacağım.
Deadlock Nedir?
Öncelikle deadlock, Türkçesiyle “kilitlenme”, iki ya da daha fazla işlemin birbirinin kilitlediği kaynakları bekleyerek sonsuza kadar takılı kalmasıdır. Düşünün, iki arkadaşınız var ve ikisi de birbirinden kalemi almayı bekliyor ama hiçbiri kalemi bırakmıyor. Sonuç: İkiniz de kâğıda yazı yazamıyorsunuz.
PostgreSQL’de Deadlock Neden Olur?
PostgreSQL’de deadlock genellikle şu durumlarda görülür:
- Farklı işlemler aynı tabloyu veya satırı farklı sırayla kilitliyor.
- Uzun süre açık kalan transaction’lar.
- Yanlış sıralanmış sorgular ve update işlemleri.
Bir örnekle açıklayalım: İşlem A tablo 1’in satırını, işlem B ise tablo 2’nin satırını kilitledi. Sonra işlem A tablo 2’ye, işlem B ise tablo 1’e erişmek istediğinde işte tam o anda deadlock patlıyor!
Deadlock’u Tespit Etmek İçin Ne Yapmalıyız?
PostgreSQL’in log dosyaları, deadlock hatasının izini sürmek için en büyük dostunuzdur. Log’larda şu satırlar yer alır:
ERROR: deadlock detected
DETAIL: Process 1234 waits for ShareLock on transaction 5678; blocked by process 91011. Ayrıca, PostgreSQL’in pg_stat_activity ve pg_locks tablolarıyla da aktif kilitleri ve bekleyen işlemleri izleyebilirsiniz.
“Transaction Deadlock Detected” Hatasını Çözmenin Yolları
Şimdi en keyifli kısma geldik! İşte deadlock’ları önlemek için uygulayabileceğiniz pratik yöntemler:
1. İşlemlerin Kilit Sırasını Standartlaştırın
Tüm transaction’larınızın aynı kaynakları aynı sırayla kilitlemesini sağlayın. Böylece birbirini bekleyen işlemler zinciri kırılır.
2. Transaction Süresini Kısaltın
Uzun süren işlemler deadlock riskini artırır. Gereksiz uzun sorguları veya güncellemeleri optimize edin, mümkünse parçalara bölün.
3. İzolasyon Seviyesini Düşürün
Varsayılan “Serializable” yerine, “Read Committed” veya “Repeatable Read” seviyeleri daha az kilitlenmeye neden olabilir.
4. Sorgu ve İndeks Optimizasyonu
Veritabanındaki indekslerin doğru kullanıldığından emin olun. Sorguları optimize etmek, kilitlerin tutulma süresini azaltır.
5. Otomatik Yeniden Deneme Mekanizması Kullanın
Deadlock oluştuğunda işlemi yeniden başlatmak bazen en pratik çözüm olur. Uygulama katmanında bu mantığı kodlayabilirsiniz.
Örnek: Basit Bir Otomatik Yeniden Deneme Kodu
DO
$$
DECLARE
attempts INTEGER := 0;
max_attempts INTEGER := 5;
BEGIN
WHILE attempts < max_attempts LOOP
BEGIN
-- Buraya transaction içi işlemlerinizi yazın
PERFORM some_update_function();
COMMIT;
EXIT;
EXCEPTION WHEN deadlock_detected THEN
attempts := attempts + 1;
RAISE NOTICE 'Deadlock detected, retry attempt %', attempts;
PERFORM pg_sleep(0.5); -- Yarım saniye bekle
END;
END LOOP;
IF attempts = max_attempts THEN
RAISE EXCEPTION 'Deadlock çözülemedi, işlemi iptal ediyorum.';
END IF;
END;
$$ LANGUAGE plpgsql;Son Söz
Deadlock hataları veritabanı uygulamalarının doğal bir parçası sayılabilir. Önemli olan, onları hızlıca fark etmek ve önlemektir. Yukarıdaki tekniklerle PostgreSQL maceranız çok daha akıcı ve sorunsuz olacak. Unutmayın, her hata aslında sizi daha iyi bir geliştirici yapar!
Başka veritabanı sorunlarında görüşmek üzere, kodlarla kalın! 🚀