İki fazlı kilitleme (Two-Phase Locking, 2PL), eşzamanlı işlemlerin serileştirilebilir bir çizelge üretmesini garanti eden klasik protokoldür. Temel iddiası güçlüdür: iki fazlı kilitleme protokolüne uyan her zamanlama serileştirilebilirdir. Ancak bu garantinin bedeli, çıkmaz (deadlock) riskinin kaçınılmaz hale gelmesidir. Protokol iki fazı şöyle tanımlar: - **Büyüme fazı (Growing Phase):** İşlem kilitler edinir, hiçbir kilit serbest bırakılmaz. - **Küçülme fazı (Shrinking Phase):** İşlem kilitler serbest bırakır, yeni kilit edinilmez. Kilit noktası (lock point), büyüme fazının bittiği andır. Serileştirilebilir çizelge oluşturmak için tüm işlemlerin kilit noktalarına göre sıralanması yeterlidir. **Strict 2PL (S2PL):** Tüm kilitler yalnızca commit veya rollback sırasında serbest bırakılır. Bu, cascading rollback problemini ortadan kaldırır; PostgreSQL ve çoğu RDBMS S2PL kullanır. **Rigorous 2PL:** Hem okuma hem yazma kilitleri commit'e kadar tutulur. ANSI SQL izolasyon seviyeleriyle tam uyum için gereklidir. Serileştirilebilirlik garantisi şu öneri ile kanıtlanır: 2PL protokolünden üretilen herhangi bir zamanlama için, işlemlerin kilit noktalarına göre sıralandığı seri çizelgeyle eşdeğer bir çizelge mevcuttur. Çatışma grafiğinde döngü oluşmasının imkansız olduğu iki fazlı kilitleme protokolü sayesinde kanıtlanabilir. Çıkmaz mekanizması şöyle oluşur: T1 A kilidini tutar ve B için bekler; T2 B kilidini tutar ve A için bekler. Bu döngüsel bekleme, iki fazlı kilitleme protokolünün doğal sonucudur çünkü protokol önceden kilit sıralaması dayatmaz. Çıkmaz çözüm stratejileri: 1. **Tespit ve kesme (Detection & Abort):** Wait-for grafiğinde döngü aranır; döngüdeki bir işlem kurban seçilip rollback yapılır. PostgreSQL bu yöntemi kullanır. 2. **Önleme (Prevention):** - *Wait-Die:* Genç işlem ölür, yaşlı işlem bekler. - *Wound-Wait:* Yaşlı işlem genci öldürür, genç işlem bekler. 3. **Timeout:** Belirli süre bekleyen işlem otomatik olarak iptal edilir. Pratik tuning açısından: `lock_timeout` ve `deadlock_timeout` PostgreSQL parametreleri, sistemin deadlock tespitine ne kadar süre sonra başlayacağını belirler. `deadlock_timeout` varsayılan değeri 1 saniyedir; yüksek trafikli sistemlerde düşürülmesi önerilir. Lock granularity de kritik bir tasarım kararıdır. Satır düzeyinde kilitleme eşzamanlılığı artırır fakat lock manager overhead'ini de yükseltir. Tablo düzeyinde kilitleme basittir ancak eşzamanlılığı ciddi biçimde kısıtlar. PostgreSQL, row-level ve table-level kilitleme arasında advisory lock mekanizmasıyla uygulama katmanına esneklik tanır.