İki kişi aynı anda takvimi açıyor. İkisinin ekranında da 14.00 boş görünüyor. İkisi de randevuyu tamamlıyor ve iki ayrı onay mesajı alıyor. Takvim ekranı doğru görünmüş olsa bile sistem aynı kaynağı iki kişiye ayırmış olabilir.
Bu sorun, yalnızca takvimi daha sık yenileyerek çözülmez. Boşluğu görmek ile rezervasyonu kesinleştirmek farklı işlemlerdir. Aralarındaki anda başka bir kullanıcı, çağrı merkezi çalışanı veya entegrasyon aynı saati alabilir.
Güvenilir bir online rezervasyon sistemi, kullanılabilirliği sunarken anlaşılır davranmalı; kesin kaydı oluştururken de eşzamanlı istekler altında iş kuralını korumalıdır. Aşağıdaki danışmanlık randevusu örneği varsayımsaldır ve teknik kararları açıklamak içindir.
Rezervasyonun kaynağını ve zaman aralığını tanımlayın
Önce neyin rezerve edildiğini belirleyin: bir çalışan, oda, araç, koltuk veya bunların birleşimi. “Salı günü 14.00” bilgisi tek başına yeterli değildir. Başlangıç, bitiş, kaynak ve geçerli durum birlikte değerlendirilmelidir.
Bir görüşme 45 dakika, hazırlık ve temizlik 15 dakika sürüyorsa kaynağın bloke edildiği aralık 60 dakika olabilir. Müşteriye görünen hizmet süresiyle operasyonel blok süresini farklı alanlarda tutmak bu ayrımı anlaşılır kılar.
Aralık sınırlarında ortak kural kullanın
14.00–15.00 ve 15.00–16.00 randevuları, arada ek tampon yoksa yan yana çalışabilir. Başlangıcı dahil, bitişi hariç aralık yaklaşımı bu durumu ifade eder: [14.00, 15.00). PostgreSQL aralık tipleri bu sınır davranışını destekler. PostgreSQL: aralık tipleri.
Saat dilimini ayrıca saklayın. Kesinleşmiş başlangıç ve bitiş anlarını UTC ile temsil etmek yararlı olabilir; kullanıcının gördüğü yerel saat ve işletmenin saat dilimi de korunmalıdır. PostgreSQL'in timezone içeren zaman damgası türü, girilen özgün saat dilimini saklamaz. Tekrarlayan yerel randevularda yaz saati değişimlerinin gelecekteki örnekleri nasıl etkileyeceğini ayrıca belirleyin. PostgreSQL: tarih ve saat türleri.
“Kontrol et, sonra ekle” neden tek başına yeterli değil?
İlk istek veritabanına “bu saat boş mu?” diye sorar ve evet cevabını alır. İkinci istek de ilk kayıt henüz oluşmadan aynı cevabı alabilir. Sonra ikisi de ekleme yapar. Bu bir yarış durumudur.
Uygulama kodunda ikinci bir kontrol bulunması ihtimali azaltabilir ama işlem eşzamanlılığa dayanıklı kurulmadıysa garanti sağlamaz. Kontrol ile kayıt arasında başka yazma işleminin araya giremeyeceği mekanizma gerekir.
Sabit saat dilimleri ve değişken süreler farklıdır
Her kaynak için önceden tanımlı, eşit uzunlukta tek kişilik dilimler varsa kaynak ve dilim kimliğinde benzersizlik kuralı kullanılabilir. Buna karşılık değişken süreli rezervasyonlarda yalnızca aynı başlangıç saatini engellemek yeterli olmaz. 14.00–15.00 ile 14.30–15.30 farklı başlar ama çakışır.
PostgreSQL'de aynı kaynak için çakışan zaman aralıklarını reddeden exclusion constraint yaklaşımı uygulanabilir. Kısıt, hangi kayıt durumlarının kapasite tükettiğiyle birlikte tasarlanmalıdır. Diğer veritabanlarında kaynak satırı kilidi veya uygun izolasyon ve tekrar deneme gibi yöntemler gerekebilir. PostgreSQL: çakışmayan aralık kısıtları.
Seçilen yöntemi kullanılan veritabanı üzerinde test edin. Kapasitesi birden fazla olan sınıf veya etkinlikte tek kişilik kaynak kuralını doğrudan kopyalamayın; kalan kapasitenin atomik kontrolü ayrı bir problemdir.
Geçici tutma ile kesin rezervasyonu ayırın
Ödeme ekranına geçen kullanıcıya sınırlı süreli bir tutma kaydı verilebilir. Bu süre işletmenin kararına bağlıdır; örneğin birkaç dakikalık tutma tasarlanabilir. Süre, ekranda açıkça görünmeli ve kapasite kuralının parçası olmalıdır.
Durumları en azından geçici tutuldu, onaylandı, iptal edildi ve süresi doldu olarak düşünün. Her geçişin hangi olayla gerçekleşeceğini yazın. Örneğin ödeme doğrulanınca geçici kayıttan onaylanmış kayda geçilir; yalnızca tarayıcının başarı sayfasına dönmesi yeterli kanıt sayılmaz.
Süre aşımı temizliğinin gecikebileceğini hesaba katın. Periyodik görev durmuşsa süresi geçmiş bir kaydın kapasiteyi sonsuza kadar kilitlememesi gerekir. Yeni rezervasyon kabulü sırasında geçerlilik kontrolü ve uygun kilitleme altında temizleme yapılabilir.
Ödeme geç gelirse ne olacak?
Tutma süresi dolduktan sonra ödeme onayı gelebilir. Kaynak bu sırada başkasına verilmişse ilk kullanıcıya otomatik kesin onay göndermek yeniden çakışma yaratır. Tasarımda yeniden uygunluk kontrolü, alternatif teklif veya iade değerlendirmesi için açık bir yol bulunmalıdır.
Ödeme hizmetiyle kendi veritabanınız arasında tek ortak işlem varmış gibi davranmayın. Her sistemin sonucu ve telafi adımı izlenebilir olsun. Operasyon çalışanı hangi kaydın manuel karar beklediğini görebilmelidir.
Tekrar denenen istekler ikinci randevu üretmemeli
Kullanıcı bağlantı kesildiğinde aynı düğmeye yeniden basabilir. Aynı işleme ait benzersiz bir idempotency anahtarı, sunucunun tekrar gelen isteği tanımasına yardımcı olur. Ancak bu kural iki farklı müşterinin aynı saati almasını engellemez; kapasite kontrolünün yerine geçmez.
Ödeme API'sinde de benzer yaklaşım bulunabilir. Stripe, aynı idempotency anahtarıyla güvenli tekrar denemeyi belgeler. Kendi rezervasyon işleminizin tekrar kontrolünü ve saklama süresini ayrıca tasarlamalısınız. Stripe: idempotent istekler.
Ödeme bildirimleri de birden fazla gelebilir. İşlenmiş olayları ve izin verilen durum geçişlerini takip edin. Stripe belgeleri olayların yinelenebileceğini ve belirli sırayla gelmelerine bağımlı olunmaması gerektiğini açıklar. Stripe: webhook işleme.
Hata durumunu kullanıcı için anlaşılır kılın
Son kayıt anında saat dolmuşsa “sunucu hatası” yerine “Bu saat az önce alındı; aşağıdaki saatlerden birini seçebilirsiniz” gibi bir açıklama gösterin. Girilen bilgileri mümkün olduğunca koruyun ve yakın alternatifleri sunun.
Onay mesajını kesin işlem tamamlandıktan sonra üretin. Bildirim hizmetindeki gecikmenin rezervasyonun kendisini belirsiz bırakmaması için panelde rezervasyon numarası ve durumu görülebilsin. E-posta gönderilememesiyle randevu oluşmamasını ayrı hata türleri olarak izleyin.
Eşzamanlılık için uygulama kontrol listesi
- Aynı kaynak ve saat için iki paralel istek çalıştırın.
- Farklı başlangıçlı ama örtüşen aralıkları deneyin.
- İptal edilmiş kaydın kapasiteyi nasıl etkilediğini sınayın.
- Çok kaynaklı randevuda tüm kaynakların birlikte ayrıldığını doğrulayın.
- Aynı işlem anahtarıyla tekrarın yeni kayıt üretmediğini kontrol edin.
- Ödeme onayını süre aşımından sonra simüle edin.
- Yinelenen ve ters sırayla gelen bildirimleri test edin.
- Rezervasyon, ödeme ve bildirim geçmişini ortak referansla izleyin.
WebWizz ile rezervasyon yazılımınızı değerlendirmek için hizmet sürelerinizi, kaynaklarınızı ve örnek çakışma senaryonuzu iletişim sayfasından paylaşabilirsiniz. Sağlam başlangıç, takvim çiziminden önce kapasite kurallarını netleştirmektir.
Sık sorulan sorular
Takvimi saniyede bir yenilemek çifte randevuyu önler mi?
Hayır. Görüntüleme ile kesin kayıt arasında yine eşzamanlı istek olabilir. Yenileme kullanıcı deneyimine yardımcı olur; asıl koruma kayıt işleminin ve veritabanı kuralının tasarımında kurulmalıdır.
Her rezervasyon sisteminde ödeme zorunlu mu?
Hayır. Ödemesiz akışlarda da geçici tutma, onay, iptal ve no-show süreçleri gerekebilir. Ödeme yoksa ilgili durumları sadeleştirin; kaynak çakışması kontrolünü koruyun.
Çağrı merkezi de aynı sistemden randevu vermeli mi?
Mümkünse bütün kanallar aynı kapasite ve kayıt kurallarını kullanmalıdır. Yönetici panelinin veritabanına farklı bir yoldan yazması, web sitesindeki korumayı etkisiz bırakabilir.
İptalden sonra aynı saat hemen açılabilir mi?
İş kuralına bağlıdır. Hazırlık, personel planı veya iade süreci ek değerlendirme gerektirebilir. “İptal edildi” durumunun kapasiteyi hangi anda serbest bıraktığı açıkça tanımlanmalıdır.