
İdempotans: Aynı İsteği İki Kez Almak Neden Sorun Olur?
Müşteri ödeme butonuna bastı, sayfa yavaş yüklendi, tekrar bastı. Şimdi iki sipariş ve iki tahsilat var. Bu, yavaş bir bağlantının değil, tasarımın ürettiği bir sorundur.
Bu yazı, tekrarlanan isteklerin nasıl zararsız hâle getirileceğini ele alıyor.
Tanım
Bir işlem, kaç kez çalıştırılırsa çalıştırılsın sonuç aynı kalıyorsa idempotanttır:
- Kaydı okumak idempotanttır.
- Durumu belirli bir değere ayarlamak idempotanttır.
- Sayacı artırmak değildir.
- Yeni kayıt oluşturmak değildir.
İkinci ve üçüncü maddeler arasındaki fark tasarımın anahtarıdır: bakiyeyi yüz liraya ayarlamak kaç kez tekrarlanırsa tekrarlansın aynı sonucu verir, ama bakiyeye on lira eklemek her tekrarda farklı bir sonuç üretir.
Mümkün olduğunda ayarlama biçimi tercih edilmelidir.
Dördüncü madde ise en sık yaşanan sorunu tarif eder ve özel bir çözüm gerektirir.
Tekrar Nereden Gelir
| Kaynak | Sıklık |
|---|---|
| Kullanıcının çift tıklaması | Çok sık |
| Sayfa yenileme | Sık |
| Dış servisin tekrar denemesi | Sık |
| Ağ zaman aşımı sonrası deneme | Kaçınılmaz |
Dördüncü satır en önemlisidir ve kaçınılmazdır: bir istek zaman aşımına uğradığında istemci işlemin gerçekleşip gerçekleşmediğini bilemez — yanıt kaybolmuş olabilir ama işlem sunucuda tamamlanmış olabilir.
Bu belirsizlik ağ üzerinde çözülemez.
Tek çözüm, tekrar denemenin zararsız olmasını sağlamaktır.
Üçüncü satır ise ödeme sağlayıcılarının bildirimlerinde sürekli yaşanır.
İdempotans Anahtarı
- İstemci benzersiz bir anahtar üretir.
- İstekle birlikte gönderir.
- Sunucu anahtarı kaydeder.
- Aynı anahtar tekrar gelirse eski sonuç döner.
Dördüncü madde işin özüdür: aynı anahtarla gelen ikinci istek yeniden işlenmez, ilk işlemin sonucu döndürülür — istemci açısından her şey normal görünür ama ikinci bir sipariş oluşmaz.
Anahtar, formun ilk gösterildiği anda üretilmelidir.
Gönderim anında üretilirse her tıklama farklı anahtar alır ve koruma çalışmaz.
Bu ayrıntı, uygulamaların çoğunda gözden kaçar.
Veritabanı Tarafında Zorlamak
- Anahtar sütununa benzersizlik kuralı koyun.
- İkinci ekleme hata verir.
- Hata yakalanıp mevcut kayıt döndürülür.
Birinci madde tek gerçekten güvenilir yöntemdir: önce sorgulayıp yoksa eklemek yarış koşuluna açıktır — iki istek aynı anda kontrol yaparsa ikisi de kayıt bulamaz ve ikisi de ekler; benzersizlik kuralı ise veritabanı seviyesinde bunu imkânsız kılar.
Bu, eşzamanlılık sorunlarının klasik çözümüdür.
Üçüncü madde ise hatayı kullanıcıya göstermeden ele alır.
Benzersizlik hatası burada bir arıza değil, beklenen bir durumdur.
Form Gönderiminde
| Önlem | Koruma düzeyi |
|---|---|
| Butonu devre dışı bırakmak | Zayıf |
| Gönderim sonrası yönlendirme | Orta |
| Tek kullanımlık form belirteci | İyi |
| Veritabanı benzersizlik kuralı | Kesin |
Birinci satır yalnızca görsel bir önlemdir: butonu tarayıcıda devre dışı bırakmak yalnızca kazara çift tıklamayı önler — isteği doğrudan tekrar gönderen bir istemciyi hiçbir biçimde durdurmaz.
Yine de kullanıcı deneyimi açısından yapılmalıdır.
İkinci satır sayfa yenilemede formun tekrar gönderilmesini engeller ve basit bir iyileştirmedir.
Ama gerçek koruma yalnızca son satırdadır.
Dış Bildirimlerde
- Bildirimin kendi kimliği vardır.
- İşlenen kimlikler kaydedilir.
- Tekrar gelen kimlik atlanır.
Bu üçlü, ödeme bildirimlerinde zorunludur: ödeme sağlayıcıları yanıt alamadıklarında aynı bildirimi tekrar tekrar gönderir — bildirimin kimliğini kaydetmezseniz aynı siparişi birden fazla kez onaylarsınız.
Bazı sağlayıcılar aynı bildirimi saatler boyunca dener.
İşlenen kimlik kaydı, makul bir süre saklanmalıdır.
Süresiz saklamak tabloyu gereksiz büyütür.
Anahtar Ömrü
- Çok kısa süre koruma sağlamaz.
- Çok uzun süre tabloyu şişirir.
- Yirmi dört saat çoğu durum için yeterlidir.
Birinci madde pratik bir hatayı işaret eder: idempotans kaydını birkaç dakika sonra silmek, ağ sorunları nedeniyle geç gelen tekrarları kaçırır — dış servislerin yeniden deneme aralıkları saatlere yayılabilir.
Süre, en uzun tekrar deneme penceresinden uzun olmalıdır.
Eski kayıtlar düzenli bir görevle temizlenir.
Bu temizlik, tablonun büyümesini kontrol altında tutar.
Sınırlar
| Durum | Davranış |
|---|---|
| Aynı anahtar, aynı veri | Eski sonuç döner |
| Aynı anahtar, farklı veri | Hata döndürülmeli |
| İlk istek hâlâ işleniyor | Bekletilmeli veya reddedilmeli |
İkinci satır güvenlik açısından önemlidir: aynı anahtarla farklı içerik gönderilirse bu bir tekrar değil, bir hatadır — sessizce eski sonucu döndürmek, gönderilen yeni verinin kaybolduğunu gizler.
Bu durumda açık bir hata mesajı verilmelidir.
Üçüncü satır ise eşzamanlı gelen iki isteği tarif eder ve kilitleme gerektirir.
Kayıt oluşturulmadan önce anahtar yazılırsa bu durum doğal olarak çözülür.
Ödeme ve sipariş akışlarının güvenilir çalışması için kesintisiz bir barındırma ortamı gerekir; paylaşımlı hosting çözümleri ile veritabanı ve uygulamanızı aynı altyapıda tutabilirsiniz.
Sonuç
Tekrarlanan istekler kaçınılmazdır çünkü bir istek zaman aşımına uğradığında istemci işlemin gerçekleşip gerçekleşmediğini bilemez. Çözüm, tekrarı engellemek değil zararsız kılmaktır: idempotans anahtarı kullanın, anahtarı formun ilk gösterildiği anda üretin ve benzersizlik kuralını veritabanı seviyesinde zorlayın — önce sorgulayıp yoksa eklemek yarış koşuluna açıktır.
Sıkça Sorulan Sorular (SSS)
Çift sipariş sorunu nasıl çözülür?
İdempotans anahtarıyla. İstemci benzersiz bir anahtar üretip istekle gönderir; aynı anahtarla gelen ikinci istek yeniden işlenmez, ilk işlemin sonucu döndürülür. Anahtar formun ilk gösterildiği anda üretilmelidir, gönderim anında değil.
Butonu devre dışı bırakmak yetmez mi?
Yetmez. Bu yalnızca kazara çift tıklamayı önler; isteği doğrudan tekrar gönderen bir istemciyi durdurmaz. Yine de kullanıcı deneyimi için yapılmalıdır, ama gerçek koruma veritabanı seviyesindeki benzersizlik kuralındadır.
Ödeme bildirimi neden birkaç kez geliyor?
Sağlayıcı yanıt alamadığında aynı bildirimi tekrar gönderir; bazıları saatler boyunca dener. Bildirimin kendi kimliğini kaydetmezseniz aynı siparişi birden fazla kez onaylarsınız. İşlenen kimlikleri saklayıp tekrar gelenleri atlayın.
Anahtar kaydını ne kadar saklamalıyım?
En uzun tekrar deneme penceresinden uzun; yirmi dört saat çoğu durum için yeterlidir. Birkaç dakika sonra silmek, ağ sorunları nedeniyle geç gelen tekrarları kaçırır. Eski kayıtları düzenli bir görevle temizleyin.