Çoğu kişi aynı kodun iki müşteriye gitmesini “stok sayımı yanlış girilmiş” ya da “sunucu o an yavaşlamış” sanır. Sabah panele bakarsın, stok eksi bir görünür, iki sipariş de başarılı yazar, iki müşteri de aynı 16 haneli kodu göndermiş. Sen de olayı kapatmak için elle bir kod daha üretip özür mesajı atarsın. Üç gün sonra aynı şey tekrar olur. Çünkü yanlış şeyi onardın: sonucu temizledin, sebebi hiç görmedin.
Bu işin adı yarış koşulu ve seni en yoğun dakikanda, yani en çok para kazandığın dakikada bulur. Bir kampanya duyurusu, bir yayıncı yönlendirmesi, bir indirim saati... Aynı saniyenin içinde iki ödeme bildirimi düşer, iki istek aynı stok satırını okur, ikisi de “bu kod müsait” cevabını alır. Kullandığın e-pin satış scripti bunu hata olarak görmez, çünkü teknik anlamda hata yoktur; sadece sıralama yoktur. Bu yazıda o sıralamasızlığı nasıl yakalayacağını, hangi izlere bakacağını ve teşhisi laf düzeyinden kanıt düzeyine nasıl çıkaracağını anlatıyorum.
Çift Satılan Kod Neden Loglarda “Başarılı” Görünür?
Yarış koşulunun en sinsi tarafı sessiz olmasıdır. Klasik bir akışta script önce stoktan boş bir kod seçer, sonra siparişi oluşturur, sonra kodu kullanıldı diye işaretler. Bu üç adım arasında birkaç milisaniyelik boşluk vardır. İki istek bu boşluğa aynı anda girdiğinde ikisi de aynı kodu seçer, ikisi de kendi siparişini başarıyla yazar. Veritabanı memnundur, script memnundur, sadece müşteri memnun değildir. Loglarda hata satırı aramak bu yüzden boşa kürek çekmektir; aranacak şey hata değil, çakışan zaman damgalarıdır.
Bu noktada birçok işletme sahibi kendini suçlar, oysa sorun disiplinle değil mimariyle ilgilidir. Kodun seçilmesiyle kilitlenmesi arasında tek bir atomik adım yoksa, yeterince trafik geldiğinde çakışma matematiksel olarak kaçınılmazdır. Dolayısıyla ilk kabul etmen gereken cümle şu: bu bir talih meselesi değil, ölçülebilir bir tasarım açığıdır. Ölçülebilir olduğu için de teşhis edilebilir.
Yarış Koşulunun Parmak İzini Saniye Değil Milisaniye Seviyesinde Aramalısın
Teşhisin ilk şartı zaman çözünürlüğünü yükseltmektir. Sipariş tablosundaki tarih alanı saniye hassasiyetindeyse, çakışan iki kayıt sana tıpatıp aynı saati gösterir ve hangisinin önce geldiğini asla bilemezsin. Mikrosaniyeli zaman damgası, isteği baştan sona takip eden bir istek kimliği ve o isteğin hangi süreç ya da işçi tarafından yürütüldüğünü söyleyen bir etiket olmadan elinde delil yok demektir. Ciddi bir dijital ürün satış scripti bu üç alanı sonradan eklenen lüks değil, varsayılan temel olarak taşır.
Sonra aynı koda dokunan bütün olayları tek bir zaman şeridine dizersin. Ödeme bildirimi geldi, stok sorgusu yapıldı, kod seçildi, kilit denendi, sipariş yazıldı, teslimat gönderildi. İki siparişin şeridi birbirinin içine geçmişse teşhis tamamdır: bu bir yarış koşuludur. Şeritler arasında saniyeler varsa başka bir yerde arayacaksın, çünkü o zaman sorun eşzamanlılık değil, muhtemelen tekrarlanan bildirim ya da elle yapılan bir müdahaledir.
| Belirti | Kök neden ihtimali | Bakacağın kanıt | Kalıcı çözüm |
|---|---|---|---|
| Aynı kod iki siparişte | Seçme ve kilitleme adımlarının ayrı olması | İki kaydın mikrosaniye farkı | Tek ifadede koşullu güncelleme |
| Stok eksiye düşüyor | Sayının uygulama tarafında hesaplanması | Stok hareket kaydındaki atlama | Stoku veritabanında azaltma |
| Tek siparişe iki teslimat | Ödeme bildiriminin iki kez düşmesi | Aynı referansla çift bildirim | Bildirim kimliğiyle tekillik |
| Bakiye iki kez düşüyor | Cüzdan güncellemesinde kilit yokluğu | Ardışık iki negatif hareket | Satır kilidi ve tek işlem bloğu |
| Sadece kampanyada oluyor | Eşzamanlılığın eşiği aşması | Dakikalık istek yoğunluğu | Kuyruk ve sıra numarası |
Teşhis İçin Kurman Gereken Üç Tuzak: Sayaç, Damga, Kilit İzi
Yarış koşulu yakalanmak istemez, bu yüzden ona tuzak kurarsın. Birinci tuzak sayaçtır: her kod için kaç kez teslimat denemesi yapıldığını ayrı bir alanda tutarsın. Bu sayı birden büyükse, kim ne derse desin çakışma vardır. İkinci tuzak damgadır: kodu kim, hangi sipariş için, hangi işçi süreciyle kilitledi bilgisini kodun yanına yazarsın. Üçüncü tuzak kilit izidir: kilit denemesinin başarılı mı başarısız mı döndüğünü loglarsın. Başarısız kilit denemeleri aslında iyi haberdir, çünkü sistemin çakışmayı fark edip durdurduğunu gösterir.
Bu üç tuzak kurulduktan sonra teşhis artık tahmine dayanmaz. Panelden tek sorguyla “sayacı birden büyük kodlar” listesini çekersin ve karşında sorunun haritası durur. Kullandığın e-pin yazılımı bu alanları sunmuyorsa, teşhis için elinde sadece müşteri şikayeti kalır ki bu da en pahalı ölçüm aracıdır.
Çift teslimat vakalarında kök neden dağılımı
- Kilitsiz kod seçimi 45%
- Tekrarlanan ödeme bildirimi 25%
- Uygulamada hesaplanan stok 20%
- Elle müdahale ve düzeltme 10%
Kasıtlı Çarpışma Testi: Yarışı Kendi Elinle Üretmeden Teşhis Bitmiş Sayılmaz
Gerçek teşhis, sorunu isteyerek tekrar üretebildiğin an tamamlanır. Test ortamında tek bir ürüne bir adet stok bırakırsın ve aynı milisaniyede on adet sipariş isteği gönderirsin. Sağlıklı bir e-pin satış yazılımı bu testte tek başarı ve dokuz temiz ret üretir; ret alanlar da “stok tükendi” mesajını görür, ödeme çekilmişse iade kuyruğuna düşer. İki başarı görürsen açık kanıtlanmıştır. On istek yerine yüz istekle tekrarladığında açığın genişliğini de ölçmüş olursun.
Bu testi ayda bir kez tekrarlamayı alışkanlık haline getir. Çünkü yarış koşulu bir kez kapanıp sonsuza kadar kapalı kalan bir delik değildir; yeni bir tedarikçi entegrasyonu, yeni bir kampanya modülü ya da teslimat akışına eklenen tek bir adım açığı geri getirebilir. Pinova gibi konumlanmış bir dijital ürün satış yazılımı tercih ediyorsan, bu tür eşzamanlılık testlerinin ürünün kendi özellik setinde nasıl karşılandığına bakman en doğrusu olur.
Kodu Satmak Değil, Kodu Rezerve Etmek: Doğru Akışın Anatomisi
Kalıcı çözümün mantığı basittir: kodu seçmeden önce sahiplen. Doğru akışta script önce boş bir kodu “bu siparişe ait” diye tek ve koşullu bir güncelleme ifadesiyle işaretler. Eğer bu güncelleme sıfır satır etkilediyse kodu başkası kapmıştır ve istek nazikçe reddedilir. Bir satır etkilendiyse kod artık senin, teslimat güvenle yapılabilir. Yani karar veritabanına devredilir, çünkü sıralamayı garanti edebilen tek yer orasıdır.
Aynı disiplin cüzdan bakiyesi, kupon kullanımı ve bayi limiti için de geçerlidir. Hepsi aynı soruyu sorar: bu kaynağı iki kişi aynı anda tüketebilir mi? Cevap evetse, orada bir yarış koşulu bekliyor. Bu yüzden iyi bir epin yazılım mimarisinde stok, bakiye ve kupon tek ve bölünmez bir işlem bloğunun içinde hareket eder.
Şüphelendiğin gün, sipariş tablosundaki kayıtları kod numarasına göre grupla ve birden fazla siparişte görünen kodları listele. Bu tek sorgu, haftalarca süren tartışmayı beş dakikada bitirir ve sana çakışmanın saatini de verir.
Teşhisten Sonra Nöbetçi Bırak: Tekrarlamayı Nasıl Görürsün?
Kapattığın açığın kapalı kaldığını bilmenin tek yolu sürekli bakan bir nöbetçidir. Her saat çalışan küçük bir kontrol, aynı kodun iki siparişte görünüp görünmediğini, stok sayısının negatife düşüp düşmediğini ve başarısız kilit denemelerinin sayısını raporlar. Bu sayı ani biçimde yükseldiğinde bu kötü haber değil, erken uyarıdır: trafiğin arttığını ve sistemin doğru davrandığını gösterir. Hiç uyarı gelmiyorsa nöbetçinin çalıştığından emin ol.
| Kontrol adımı | Ne arıyorsun | Sıklık | Geçti sayılma ölçütü |
|---|---|---|---|
| Çift kod sorgusu | İki siparişte görünen kod | Günlük | Sıfır kayıt |
| Negatif stok taraması | Eksiye düşen ürün | Günlük | Sıfır ürün |
| Kasıtlı çarpışma testi | Tek başarı, çok ret | Aylık | Tam olarak bir başarı |
| Bildirim tekilliği | Aynı referansla çift kayıt | Haftalık | Reddedilen tekrar sayısı |
| Kilit izi grafiği | Başarısız kilit oranı | Sürekli | Ani sıçrama yokluğu |
| Cüzdan mutabakatı | Hareket toplamı ile bakiye farkı | Günlük | Fark sıfır |
Stok kayıtlarını tahmine bırakma
Eşzamanlı siparişte kodu kilitleyen, çift teslimatı baştan engelleyen bir altyapıyla çalışmak ilk günden fark eder. Fiyatlandırmayı buradan inceleyebilirsin.
Yarış koşulu az trafikli sitelerde de olur mu?
Olur, sadece daha seyrek görünür. Tek bir kampanya duyurusu ya da iki kez düşen bir ödeme bildirimi yeterlidir. Düşük trafik açığı kapatmaz, yalnızca gizler.
Sunucuyu güçlendirmek bu sorunu çözer mi?
Çözmez, çoğu zaman gizler. Daha hızlı sunucu çakışma penceresini kısaltır ama kaldırmaz. Çözüm donanımda değil, kodun stoku kilitleme biçimindedir.
Çift satılan kodu müşteriye nasıl açıklarım?
Kısa ve net ol: teknik bir çakışma olduğunu, yerine geçerli bir kod tanımlandığını söyle ve iadeyi kendin teklif et. Sessiz kalmak, hatanın kendisinden daha çok güven kaybettirir.
Teşhis için hangi kaydı mutlaka tutmalıyım?
Mikrosaniyeli zaman damgası, istek kimliği ve kilit deneme sonucu. Bu üçü olmadan çakışmayı kanıtlamak neredeyse imkansızdır.
Yarış koşulu teşhisi aslında bir olgunluk göstergesidir: sistemine artık inanmıyorsun, ölçüyorsun. Bu yazıdaki tuzakları kurup kasıtlı çarpışma testini bir kez çalıştırdığında, satış hacmi arttıkça rahatlayan bir işletmeye dönüşürsün. Kendi altyapında bu kontrollerin nasıl karşılık bulduğunu görmek istiyorsan canlı demo üzerinden sipariş akışını baştan sona kendin deneyebilir, stok kilitleme davranışını kendi gözünle test edebilirsin.

