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

> Kilitleri tek bir global sırada, artan PK gibi, alın; transaction'ı kısa ve dar tutun, hedefli `FOR UPDATE` kullanın, kalanı backoff ile retry edin.

- Soruldu: 2026-06-02
- Yanıtlandı: 2026-06-05
- Soran: Sinan
- Etiketler: dayaniklilik, veritabani, postgresql
- Kaynak: https://muhammetsafak.com/tr/sor-bakalim/veritabani-deadlock-tespiti-ve-onleme-kurallari/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**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?


Kısa cevap: Yaşadığınız ş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ız deadlock'u kökünden çözersiniz.

## Kısa cevap

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. Deadlock'un kaçınılmaz kalan payını retry ile karşılayacağınız için, işlemin idempotent olması şart — aynı disiplinin ödeme tarafındaki hâlini [mükerrer bildirim ve idempotency kaydında](/tr/sor-bakalim/webhook-mukerrer-bildirim-idempotency-ve-hmac/) ele almıştım.

## Neden

1. **Deadlock tutarsız sıranın sonucudur.** İki transaction da kilitleri aynı sırada isterse döngü matematiksel olarak oluşamaz.

2. **Uzun transaction çakışma penceresini büyütür.** Kilit ne kadar uzun tutulursa, başka birinin ona çarpma olasılığı o kadar artar.

3. **İzolasyon seviyesini yükseltmek çözüm değildir.** Sık yapılan hata budur; genelde işe yaramaz, tam tersine daha çok kilit ekler.

## Ne yapmalı

1. **Kilitleri her zaman aynı global sırada alın.** En önemli kural. Satırları her yerde aynı deterministik düzende kilitleyin — örneğin her zaman artan primary key sırasıyla.

2. **Transaction'ı kısa ve dar tutun.** Yavaş/harici işi (API çağrısı, dosya yazımı, kullanıcı beklemesi) transaction'ın **dışına** alın; kilidi mümkün olduğunca geç alın, kısa tutun.

3. **En az satıra dokunun, hedefli kilitleyin.** Geniş kilitler yerine sadece ihtiyacınız olan satıra `SELECT ... FOR UPDATE` uygulayın.

4. **Mümkünse tek statement kullanın.** Tek bir `UPDATE`/`INSERT ... ON CONFLICT` kullandığınızda kilit sıralamasını DB yönetir.

5. **Yine de deadlock olacağını kabul edin, retry edin.** DB bir transaction'ı "kurban" seçip abort eder; bunu beklenen bir durum olarak ele alın, işlemi idempotent yapın ve backoff ile yeniden deneyin.

**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. Döngüyü kırın, izolasyonu zorlamayın.

## İlgili Yazılar

- [WAL arşivleme ve PITR ile felaketten saniyeler öncesine nasıl dönerim?](https://muhammetsafak.com/tr/sor-bakalim/veritabani-pitr-ve-wal-arsivleme-ile-felaket-oncesine-donmek/) — Sor Bakalım
- [PostgreSQL split-brain'i quorum ve mutabakat ile nasıl önlerim?](https://muhammetsafak.com/tr/sor-bakalim/postgresql-split-brain-quorum-ve-mutabakat-ile-onlemek/) — Sor Bakalım
- [Heap erişimini önlemek ve index-only scan almak için covering index'e (INCLUDE) ne zaman geçmeliyim?](https://muhammetsafak.com/tr/sor-bakalim/index-only-scan-covering-indexe-ne-zaman-gecmeliyim/) — Sor Bakalım
