dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/Hata Teşhis Kütüphanesi/postgresql-could-not-serialize-access-concurrent-update
PostgreSQL
PostgreSQL 14–18İşlemler & Eşzamanlılık
9 dk okuma
ERROR: could not serialize access due to concurrent update (SQLSTATE 40001)

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.

İnceleyen:Principal Database Reliability Architect
Test Edilen Sürümler: PostgreSQL 18.6 & 17.11 (Alpine Linux / Docker 29.7) | Tarihsel: PostgreSQL 14, 15, 16

Operasyonel Doğrulama & Güvenilirlik Standardı

Son Teknik İnceleme: 30 Ekim 2026
Test Edilen SürümlerPostgreSQL 18.6 & 17.11 (Alpine / Docker 29.7) | Tarihsel: 14.10, 15.6, 16.4
Gerekli YetkiREPEATABLE READ veya SERIALIZABLE yalıtım düzeyinde işlem yürüten standart DML yetkisi
Risk Seviyesi
Medium40001 hatasını susturmak için yalıtım düzeyini körlemesine READ COMMITTED yapmak veri bütünlüğü anomalilerine (write skew) yol açar
Beklenen ÇıktıUygulama katmanında exponential backoff + jitter içeren retry döngüsünün ve DEFERRABLE işlemlerin devreye alınması
Geri Dönüş (Rollback) Planı:İşlemleri olabildiğince kısa tutma, SELECT FOR UPDATE ile sıcak satırları erken kilitleme ve retry protokolü uygulama
PostgreSQL Docs: Serializable Snapshot Isolation (SSI)
İlk 60 Saniye Teşhis Protokolü:

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

plaintext
ERROR: could not serialize access due to concurrent update

Veya Serializable Snapshot Isolation (SSI) motorundan gelen şu detaylı varyant:

plaintext
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).

ÖNEMLİ
Bu Hata Bir Arıza Değildir; Veri Bütünlüğü Kalkanıdır! Bu hatayı bir yazılım çöküşü veya veritabanı arızası olarak yorumlamak baştan yanılgıya düşürür. PostgreSQL burada bir şeyi bozmamış, tam tersine verinizin tutarlılığını korumuştur. İki eşzamanlı işlem aynı anda çalışırken, bu işlemlerin üretmek istediği sonuç işlemleri arka arkaya tek tek (seri olarak) çalıştırmakla elde edilemeyecek bir anomaliye (örneğin *Write Skew*) yol açtığında, PostgreSQL bu iki işlemden birini bilerek iptal eder. Mesajın 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 COMMIT anı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

sql
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:

sql
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:

plaintext
40001 (serialization_failure) → YENİDEN DENE 40P01 (deadlock_detected) → YENİDEN DENE

Kurallar:

  • •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 ... COMMIT bloğ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:

sql
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:

sql
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.

DİKKAT / TEHLİKE
Yalıtım Düzeyini Düşürme Tuzağı: 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ı

Diğer Veritabanı Hata Teşhisleri

Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.

Tüm Hatalar (50)