İçeriğe geç
Muhammet Şafak
en
Soran: Sinan Cevaplandı:

Veritabanı deadlock'larını önlemek için hangi kurallara dikkat etmeliyim?


Soru

İki transaction eşzamanlı çalışıyor. A, Tablo1'deki X'i kilitledi ve Tablo2'deki Y'yi güncellemek istiyor; aynı anda B, Tablo2'deki Y'yi kilitledi ve Tablo1'deki X'i güncellemek istiyor. İkisi de sonsuza kadar birbirini bekliyor. Uygulama kodunda DB işlemlerini tasarlarken deadlock riskini minimize etmek için hangi kurallara (kilit sıralaması, kısa transaction vb.) dikkat etmeliyim?

Cevap

Kısa cevap: Yaşadığın şey klasik bir kilit-sıralama döngüsü: A önce X’i sonra Y’yi, B önce Y’yi sonra X’i kilitliyor. Döngüyü kırarsan deadlock’u kökünden çözersin.

Asıl mesele şu: deadlock şanssızlık değil, tutarsız kilit sırasının matematiksel sonucu. İki transaction kilitleri farklı sırayla isteyince, bir döngü oluşur ve ikisi de birbirini bekler.

  1. Kilitleri her zaman aynı global sırada al. Bu en önemli kural. Satırları her yerde aynı deterministik düzende kilitle — örneğin her zaman artan primary key sırasıyla. İki transaction da X’i Y’den önce kilitlerse, döngü asla oluşamaz; biri diğerini bekler ve biter.
  2. Transaction’ı kısa ve dar tut. Yavaş/harici işi (API çağrısı, dosya yazımı, kullanıcı beklemesi) transaction’ın dışına al. Kilidi mümkün olduğunca geç al, mümkün olduğunca kısa tut. Transaction ne kadar uzun açık kalırsa, çakışma penceresi o kadar büyür.
  3. En az satıra dokun, hedefli kilitle. Geniş kilitler yerine sadece ihtiyacın olan satıra SELECT ... FOR UPDATE uygula. Gereğinden fazla satır kilitlemek, çakışma yüzeyini büyütür.
  4. Mümkünse tek statement kullan. İşi mümkünse tek bir UPDATE/INSERT ... ON CONFLICT ile yap; bu durumda kilit sıralamasını DB senin için yönetir ve uygulama tarafında döngü kurma riskini ortadan kaldırırsın.
  5. Yine de deadlock olacağını kabul et, retry et. Tüm önlemlere rağmen ara sıra deadlock olur; DB bir transaction’ı “kurban” seçip abort eder. Bunu bir hata değil, beklenen bir durum olarak ele al: işlemi idempotent yap ve backoff ile yeniden dene.

Sonuç: Ben olsam tutarlı kilit sırası + kısa transaction + deadlock’ta retry üçlüsünü kurardım. Sık yapılan hata şu: izolasyon seviyesini yükselterek deadlock’u çözmeye çalışmak. Bu genelde işe yaramaz, tam tersine daha çok kilit ekler. Döngüyü kır, izolasyonu zorlama.

Etiketler: #dayanıklılık#veritabanı#postgresql
Paylaş:

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

Diğer Sorular

Tüm sorular

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi