PostgreSQL 40001 — Bu Hata Neden Bir Arıza Değil?
40001 serileştirme hatasının REPEATABLE READ ve SERIALIZABLE'daki farkı, doğru retry döngüsü ve DEFERRABLE salt-okunur işlemler.
Operasyonel Doğrulama & Güvenilirlik Standardı
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
ERROR: could not serialize access due to concurrent updateVeya Serializable Snapshot Isolation (SSI) motorundan gelen şu detaylı varyant:
ERROR: could not serialize access due to read/write dependencies among transactions
DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt.
HINT: The transaction might succeed if retried.SQLSTATE hata kodu: 40001 (serialization_failure).
HINT satırı reçeteyi açıkça verir: *"The transaction might succeed if retried."*Bu hata yalnızca REPEATABLE READ ve SERIALIZABLE yalıtım düzeylerinde oluşur. READ COMMITTED altında PostgreSQL sonradan yazanı bekletir veya ezer. Yani bu hatayı görüyorsanız, sisteminizin yüksek bir izolasyon düzeyinde çalıştığını anlarsınız.
▸`DETAIL` Satırındaki Reason Code Ne Anlatıyor?
- •`Canceled on identification as a pivot, during commit attempt`: İşleminiz diğer iki işlem arasında bağımlılık grafiğinde köprü (pivot) haline gelmiştir ve iptal kararı tam
COMMITanında verilmiştir. Tüm işi yapıp tam bitirirken kaybetmek anlamına gelir; retry maliyeti en yüksek olan varyanttır. - •`Canceled on conflict out to pivot`: İşleminiz dışa doğru bir okuma/yazma çakışması tespit edilerek elenmiştir.
- •`Canceled on identification as a pivot, during write`: Çakışma
COMMITöncesinde, bir yazma ifadesi yürütülürken erken tespit edilmiştir.
▸Nedenini Doğrulayan Teşhis Sorguları
1. Yürürlükteki Yalıtım Düzeyini Kontrol Edin
SHOW default_transaction_isolation;Bağlantı havuzlayıcı (PgBouncer) veya uygulama ORM kütüphanesi oturum başında SET TRANSACTION ISOLATION LEVEL göndererek sunucu varsayılanını ezmiş olabilir.
2. Uzun Süren Açık İşlemleri Tespit Edin
İşlemler ne kadar uzun süre açık kalırsa, serileştirme çakışması olasılığı katlanarak artar:
SELECT pid, state, backend_xid, xact_start, now() - xact_start AS sure,
left(query, 90) AS sorgu
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY xact_start;▸Adım Adım Kalıcı Çözüm
1. Uygulama Katmanında Zorunlu Retry (Yeniden Deneme) Protokolü Kurun
SERIALIZABLE veya REPEATABLE READ kullanan bir uygulamada retry kodu bir lüks değil, mimari bir zorunluluktur:
40001 (serialization_failure) → YENİDEN DENE
40P01 (deadlock_detected) → YENİDEN DENEKurallar:
- •Sınırlı sayıda deneme (genellikle 3 ila 5 deneme).
- •Üstel geri çekilme (exponential backoff) ve rastgele titreme (jitter) ekleyin.
- •Kritik: Yeniden deneme yalnızca işlemin tamamını (baştan sona
BEGIN ... COMMITbloğunu) kapsamalıdır; aradaki tek bir SQL ifadesini retry etmek durumu kurtarmaz. - •İşlem içinde harici API çağrısı (ödeme alma, e-posta atma) olmamalıdır; aksi halde retry sırasında ödeme iki kez çekilebilir! Yan etkileri *Transactional Outbox* deseniyle ayırın.
2. İşlem Sürelerini Kısaltın
Kullanıcı girdisi bekleyen, dosya yükleyen veya mikroservis çağıran blokları transaction sınırlarının tamamen dışına çıkarın.
3. Sıcak Satırları Erken Kilitleyin (SELECT FOR UPDATE)
Aynı satırı okuyup sonra güncelleyen bir iş akışında, çakışmayı commit anında 40001 ile öğrenmek yerine baştan satır kilidi alarak rakipleri beklemeye alın:
SELECT bakiye FROM hesap WHERE id = 42 FOR UPDATE;4. Uzun Raporlarda READ ONLY DEFERRABLE Kullanın
PostgreSQL'in en güçlü özelliklerinden biri: Ertelenebilir salt-okunur serileştirilebilir işlemler çakışma üretmez:
BEGIN;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY, DEFERRABLE;
-- Uzun süren analitik rapor sorguları
COMMIT;Bu işlem, veritabanında tutarlı bir anlık görüntü hazır olana kadar başlangıçta birkaç milisaniye bekleyebilir; ancak başladığı andan itibaren asla 40001 hatasıyla iptal edilmez ve diğer yazma işlemlerini de engellemez.
40001 hatasından kurtulmak için akla ilk gelen "yalıtım düzeyini READ COMMITTED yapalım" refleksi büyük bir tuzaktır. Serileştirme size iş kurallarınızın asla bozulmayacağı garantisini veriyordu. Düzeyi düşürmek hatayı susturur, ancak aylar sonra finansal tablolarınızda "kasa bakiyesi eksiye düştü" veya "aynı odaya iki kişi rezervasyon yaptı" sorunlarıyla karşılaşırsınız.▸İlgili Hata Rehberleri & Hub Bağlantıları
- •PostgreSQL Deadlock Detected (H-27) — Karşılıklı kilitlenme ve retry mimarisi
- •PostgreSQL Canceling Statement Timeout (H-37) — Sorgu zaman aşımları
- •MySQL Deadlock Found (H-05) — MySQL deadlock retry standardı
- •PostgreSQL Hub — Eşzamanlılık ve transaction tasarım rehberleri
Diğer Veritabanı Hata Teşhisleri
Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.
PostgreSQL Bağlantı Tükenmesi ve too many clients Teşhisi
FATAL: sorry, too many clients already ve remaining connection slots hatalarının üç temel kök nedeni, yetki sınırlarıyla salt okunur pg_stat_activity teşhisi ve kalıcı iki katmanlı havuzlama çö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.
PostgreSQL connection refused: 8 Adımda Kesin Teşhis
Connection refused, timeout ve "no pg_hba.conf entry" arasındaki fark; listen_addresses, port, firewall ve Docker port yayınlama kontrolleri.