hosting

Sınırlı Kupon ve Stok: Aynı Anda İki Kişi Kullanırsa

Yarış koşulunun nedeni, koşullu güncelleme ile atomik çözüm, stok rezervasyonu ve eşzamanlılık testi rehberi. Sınırlı Kupon ve Stok: Aynı Anda İki Kişi…

Sınırlı Kupon ve Stok: Aynı Anda İki Kişi Kullanırsa
İçindekiler
  1. Yarış Koşulu Nasıl Oluşur?
  2. Çözüm Yaklaşımları
  3. Stok Düşme
  4. Aşırı Satış Kabul Edilebilir mi?
  5. Çok Sunuculu Ortamda
  6. Kullanıcı Deneyimi
  7. Test Etmek
  8. Sonuç
  9. Sıkça Sorulan Sorular (SSS)
  10. Kod doğru ama limit neden aşılıyor?
  11. En basit çözüm nedir?
  12. Stoğu ne zaman düşmeliyim?
  13. Nasıl test ederim?

Sınırlı Kupon ve Stok: Aynı Anda İki Kişi Kullanırsa

100 adetlik bir kampanya kuponu tanımladınız. Kampanya bitti ve raporda 107 kullanım göründü. Kod doğru yazılmış, sayaç kontrol ediliyor — ama yedi kişi aynı anda tıklamış.

Bu yazı, sınırlı kaynakların eşzamanlı kullanımını ele alıyor.

Yarış Koşulu Nasıl Oluşur?

Klasik kod akışı şöyledir:

  1. Kullanım sayısını oku.
  2. Limitin altında mı kontrol et.
  3. Kuponu uygula.
  4. Sayacı bir artır.

Sorun birinci ile dördüncü adım arasındaki boşluktadır: okuma ile yazma arasında geçen milisaniyelerde başka istekler de aynı değeri okur — hepsi limitin altında olduğunu görür ve hepsi kuponu uygular.

Bu, düşük trafikte hiç yaşanmaz. Bir kampanya duyurusundan sonraki ilk saniyelerde ise kaçınılmazdır.

Kodda hata yoktur; varsayım hatalıdır. Kod, iki isteğin aynı anda çalışmayacağını varsayar.

Çözüm Yaklaşımları

Yöntem Güvenilirlik
Kodda kontrol Yetersiz
Koşullu güncelleme Güvenilir ve basit
Satır kilidi Güvenilir
Benzersiz kayıt kısıtı Çok güvenilir

İkinci satır en zarif çözümdür ve ek karmaşıklık gerektirmez: "kullanım sayısı limitin altındaysa bir artır" şeklinde tek bir koşullu güncelleme çalıştırmak, kontrolü ve yazmayı tek bir atomik işlemde birleştirir.

Etkilenen satır sayısı sıfır dönerse kupon tükenmiş demektir. Bu bilgi yarış koşulu olmadan elde edilir.

Dördüncü satır ise farklı bir soruyu çözer: aynı kullanıcının kuponu iki kez kullanmasını engeller.

Kullanıcı ve kupon çiftinde benzersiz bir kısıt tanımlamak, ikinci denemeyi veritabanı seviyesinde reddeder.

Stok Düşme

Aynı mantık ürün stoğu için de geçerlidir ama fazladan bir zorluk taşır:

  • Sepete eklerken düşülmeli mi?
  • Ödeme başlarken mi?
  • Ödeme onaylanınca mı?

Üç seçeneğin de sorunları vardır ve seçim iş modeline bağlıdır: sepete eklerken düşerseniz, alışverişi tamamlamayan kullanıcılar stoğu boşuna kilitler; onay anında düşerseniz iki kullanıcı aynı son ürünü ödeyebilir.

Yaygın çözüm ikinci seçenektir: ödeme başlarken stok geçici olarak ayrılır ve belirli bir süre sonra serbest bırakılır.

Bu rezervasyon süresi makul olmalıdır; çok kısa tutmak kullanıcıyı ödeme sırasında mağdur eder.

Süre dolan rezervasyonları temizleyen bir görev de gereklidir.

Aşırı Satış Kabul Edilebilir mi?

Ürün türü Tolerans
Dijital ürün Sınırsız, sorun yok
Stoktan satış Kesin sınır gerekir
Tedarikli ürün Küçük aşım kabul edilebilir
Etkinlik bileti Kesin sınır gerekir

Üçüncü satır ticari bir tercih olabilir: bazı işletmeler küçük bir aşırı satışı kabul edip müşteriye kısa bir gecikme bildirmeyi, katı kilitlerin getirdiği performans maliyetine tercih eder.

Bu, teknik bir karar değil iş kararıdır ve teknik ekip tarafından tek başına verilmemelidir.

İkinci ve dördüncü satırlarda ise aşım kabul edilemez; iptal ve iade süreci hem maliyetli hem itibar zedeleyicidir.

Çok Sunuculu Ortamda

Uygulama seviyesindeki çözümler yetersiz kalır:

  1. Bellek içi kilit tek sunucuda çalışır.
  2. Diğer sunucular onu görmez.
  3. Ortak bir kaynak gerekir.

Birinci madde çok yapılan bir hatadır: tek sunucuda mükemmel çalışan bir bellek kilidi, ikinci sunucu eklendiği gün sessizce işlevini kaybeder ve yarış koşulu geri döner.

Bu, yatay ölçekleme sonrası ortaya çıkan gizli hataların klasik nedenlerinden biridir.

Doğru yaklaşım, eşzamanlılık kontrolünü veritabanında veya paylaşılan bir bellek deposunda yapmaktır. Bu bileşenler tüm sunucular tarafından görülür.

Kullanıcı Deneyimi

Teknik doğruluk yetmez, mesaj da doğru olmalıdır:

  • Tükendiğini net söyleyin.
  • Genel hata mesajı vermeyin.
  • Alternatif sunun.
  • Sepetteki tutarı güncelleyin.

Dördüncü madde ciddi bir güven sorununu önler: kupon tükendiği hâlde sepette indirimli tutar görünmeye devam ederse, kullanıcı ödeme ekranında farklı bir rakamla karşılaşır ve alışverişi terk eder.

Tutarın hangi anda kesinleştiği net olmalıdır.

İkinci madde ise destek yükünü azaltır. "Bir hata oluştu" mesajı alan kullanıcı destek yazar; "kupon tükendi" mesajı alan kullanıcı anlar.

Test Etmek

Test Yöntem
Eşzamanlı istek Aynı anda çok istek gönderin
Son bir adet senaryosu Limiti bire indirin
Rezervasyon süresi Süreyi kısaltıp deneyin
Sayaç doğruluğu Test sonrası kayıtları sayın

İkinci satır en verimli test yöntemidir: limiti bire indirip aynı anda on istek göndermek, yarış koşulunu neredeyse kesin olarak ortaya çıkarır — yüz limitle test etmek sorunu gizler.

Bu test, kod değişikliği sonrası tekrarlanmalıdır.

Dördüncü satır ise doğrulamadır. Kayıt sayısı ile sayaç değeri uyuşmuyorsa mantıkta bir boşluk vardır.

Bu tür eşzamanlılık testlerini kendi hesabınızda çalıştırabilirsiniz; Linux hosting paketi üzerinde bir test alt alan adı kurup gerçek koşullarda deneyebilirsiniz.

Sonuç

Kupon ve stok aşımının nedeni kod hatası değil, hatalı bir varsayımdır: okuma ile yazma arasında geçen milisaniyelerde başka istekler de aynı değeri okur ve hepsi limitin altında olduğunu görür. Çözüm basittir — "limitin altındaysa bir artır" şeklinde tek bir koşullu güncelleme, kontrolü ve yazmayı atomik hâle getirir. Yatay ölçeklemede dikkat edin: tek sunucuda çalışan bir bellek kilidi, ikinci sunucu eklendiği gün sessizce işlevini kaybeder.

Sıkça Sorulan Sorular (SSS)

Kod doğru ama limit neden aşılıyor?

Çünkü kod, iki isteğin aynı anda çalışmayacağını varsayıyor. Okuma ile yazma arasındaki milisaniyelerde başka istekler de aynı değeri okur, hepsi limitin altında olduğunu görür ve hepsi işlemi uygular. Düşük trafikte hiç yaşanmaz, kampanya duyurusundan sonraki ilk saniyelerde kaçınılmazdır.

En basit çözüm nedir?

Koşullu güncelleme: "kullanım sayısı limitin altındaysa bir artır" şeklinde tek bir sorgu çalıştırın. Bu, kontrolü ve yazmayı tek atomik işlemde birleştirir. Etkilenen satır sayısı sıfır dönerse kupon tükenmiştir ve bu bilgi yarış koşulu olmadan elde edilir.

Stoğu ne zaman düşmeliyim?

Yaygın çözüm ödeme başlarken geçici rezervasyon yapmaktır. Sepete eklerken düşerseniz alışverişi tamamlamayanlar stoğu boşuna kilitler; yalnızca onay anında düşerseniz iki kullanıcı aynı son ürünü ödeyebilir. Rezervasyon süresini makul tutun ve süresi dolanları temizleyen bir görev kurun.

Nasıl test ederim?

Limiti bire indirip aynı anda on istek gönderin — bu, yarış koşulunu neredeyse kesin ortaya çıkarır. Yüz limitle test etmek sorunu gizler. Test sonrası kayıt sayısı ile sayaç değerini karşılaştırın; uyuşmuyorsa mantıkta boşluk vardır.