İş Kurallarını ve Doğruluk Kaynağını Netleştirin
Stok azaltma, rezervasyon ve sipariş oluşturma akışlarında temel risk yalnızca gecikme değildir. Aynı ürünün iki istek tarafından satılması, başarısız işlemin stoğu kilitlemesi veya önbelleğin güncel durumu maskelemesi veri bütünlüğünü bozabilir. Uygulamaya başlamadan şu kuralları açıkça tanımlayın:
Atomik Güncelleme ve Transaction Sınırları
Önce stok değerini okuyup daha sonra güncellemek yarış koşuluna açıktır. İki istek aynı değeri okursa biri diğerinin güncellemesini ezebilir. Koşulu güncellemenin parçası yapın:
Etkilenen satır sayısını mutlaka kontrol edin. Sonuç bir ise stok ayrılmıştır; sıfır ise ürün bulunamıyor veya stok yetersizdir. Bu iki durumu uygulama ve metriklerde ayırmak, teknik hatalarla gerçek stok yetersizliğini karıştırmayı önler.
Stok hareketi, rezervasyon kaydı ve sipariş durum değişikliği aynı atomik iş kuralının parçalarıysa bunları tek transaction içinde tamamlayın. Buna karşılık ödeme sağlayıcısı, e-posta servisi veya başka bir dış sistemi açık transaction sırasında çağırmayın. Uzun ağ beklemeleri kilitleri ve bağlantı havuzunu tüketebilir. Bunun yerine değişikliği ve bir outbox kaydını aynı transaction içinde commit edin; outbox kaydını daha sonra güvenli bir worker yayınlasın.
Isolation, Kilitler ve Yeniden Deneme
Isolation seviyesini varsayılan ayara bırakarak yarış koşulunun çözüldüğünü varsaymayın. Read committed çoğu koşullu güncelleme için başlangıç noktası olabilir; ancak birden fazla okumanın tek ve tutarlı bir görünüm oluşturması gerekiyorsa daha güçlü izolasyon gerekebilir. Serializable daha sıkı koruma sağlarken çatışma, bekleme ve yeniden deneme maliyetini artırır.
Cache, Queue ve İdempotent Worker Tasarımı
Cache hit sonucu stok yeterli görünse bile nihai kontrol transaction içinde veritabanında yapılmalıdır. Yazma sonrasında invalidation başarısız olabilir; bu nedenle TTL tek başına tutarlılık garantisi değildir. Kritik akışlarda cache gecikmesini ve tutarsızlık süresini görünür kılın.
Queue sistemlerinde mesajın en az bir kez teslim edilebileceğini varsayın. Worker aynı mesajı tekrar işlediğinde stok ikinci kez düşmemelidir. Olay kimliği veya iş anahtarı için benzersiz kısıt kullanın ve işlenmiş mesaj kaydını ilgili stok değişikliğiyle aynı transaction içinde oluşturun. Kuyruk sırası garanti edilmiyorsa rezervasyon oluşturma, iptal ve süresi dolma olaylarının hangi sürüm veya durum koşuluyla uygulanacağını belirleyin.
Ölçümleme, Yük Testi ve Veri Doğrulama
Başarı yalnızca HTTP 200 oranı değildir. İşlem türü, ürün veya tenant gibi anlamlı boyutlarla şu göstergeleri izleyin:
Stok azaltma, rezervasyon ve sipariş oluşturma akışlarında temel risk yalnızca gecikme değildir. Aynı ürünün iki istek tarafından satılması, başarısız işlemin stoğu kilitlemesi veya önbelleğin güncel durumu maskelemesi veri bütünlüğünü bozabilir. Uygulamaya başlamadan şu kuralları açıkça tanımlayın:
- Stok hiçbir koşulda sıfırın altına inebilir mi?
- Rezervasyon hangi durumda oluşturulur, ne zaman kesinleşir ve süresi dolunca nasıl serbest bırakılır?
- Sipariş, stok düşümü ve rezervasyon kaydı aynı transaction içinde mi yönetilecek?
- Ödeme başarısız olduğunda hangi durum geçişleri geri alınacak?
- Aynı isteğin timeout veya retry sonrasında ikinci kez işlenmesi nasıl engellenecek?
Atomik Güncelleme ve Transaction Sınırları
Önce stok değerini okuyup daha sonra güncellemek yarış koşuluna açıktır. İki istek aynı değeri okursa biri diğerinin güncellemesini ezebilir. Koşulu güncellemenin parçası yapın:
UPDATE inventory
SET available = available - :quantity
WHERE product_id = :product_id
AND available >= :quantity;
Etkilenen satır sayısını mutlaka kontrol edin. Sonuç bir ise stok ayrılmıştır; sıfır ise ürün bulunamıyor veya stok yetersizdir. Bu iki durumu uygulama ve metriklerde ayırmak, teknik hatalarla gerçek stok yetersizliğini karıştırmayı önler.
Stok hareketi, rezervasyon kaydı ve sipariş durum değişikliği aynı atomik iş kuralının parçalarıysa bunları tek transaction içinde tamamlayın. Buna karşılık ödeme sağlayıcısı, e-posta servisi veya başka bir dış sistemi açık transaction sırasında çağırmayın. Uzun ağ beklemeleri kilitleri ve bağlantı havuzunu tüketebilir. Bunun yerine değişikliği ve bir outbox kaydını aynı transaction içinde commit edin; outbox kaydını daha sonra güvenli bir worker yayınlasın.
Isolation, Kilitler ve Yeniden Deneme
Isolation seviyesini varsayılan ayara bırakarak yarış koşulunun çözüldüğünü varsaymayın. Read committed çoğu koşullu güncelleme için başlangıç noktası olabilir; ancak birden fazla okumanın tek ve tutarlı bir görünüm oluşturması gerekiyorsa daha güçlü izolasyon gerekebilir. Serializable daha sıkı koruma sağlarken çatışma, bekleme ve yeniden deneme maliyetini artırır.
- Transaction süresi, kilit bekleme süresi ve bağlantı havuzu kullanımı ölçülüyor mu?
- Birden fazla kaynağın kilitlendiği akışlarda kilit sırası bütün kod yollarında aynı mı?
- Deadlock ve serialization failure hataları güvenli biçimde yeniden deneniyor mu?
- Retry işlemi idempotent mi; aynı stok hareketi ikinci kez uygulanabiliyor mu?
Cache, Queue ve İdempotent Worker Tasarımı
Cache hit sonucu stok yeterli görünse bile nihai kontrol transaction içinde veritabanında yapılmalıdır. Yazma sonrasında invalidation başarısız olabilir; bu nedenle TTL tek başına tutarlılık garantisi değildir. Kritik akışlarda cache gecikmesini ve tutarsızlık süresini görünür kılın.
Queue sistemlerinde mesajın en az bir kez teslim edilebileceğini varsayın. Worker aynı mesajı tekrar işlediğinde stok ikinci kez düşmemelidir. Olay kimliği veya iş anahtarı için benzersiz kısıt kullanın ve işlenmiş mesaj kaydını ilgili stok değişikliğiyle aynı transaction içinde oluşturun. Kuyruk sırası garanti edilmiyorsa rezervasyon oluşturma, iptal ve süresi dolma olaylarının hangi sürüm veya durum koşuluyla uygulanacağını belirleyin.
Ölçümleme, Yük Testi ve Veri Doğrulama
Başarı yalnızca HTTP 200 oranı değildir. İşlem türü, ürün veya tenant gibi anlamlı boyutlarla şu göstergeleri izleyin:
- Transaction süresi ile p95 ve p99 gecikme
- Kilit bekleme, deadlock ve serialization failure sayısı
- Stok yetersizliği, teknik hata ve retry oranları
- Queue gecikmesi, tekrar teslim, başarısız ve poison message sayısı
- Cache invalidation başarısızlıkları ve tutarsızlık süresi
- Süresi dolduğu halde serbest bırakılmayan rezervasyonlar