İki kişi tuvalin ortasındaki aynı 6 × 4'lük bölgeyi beğendi. İkisi de alanı seçti, ikisi de aynı saniye içinde siparişi onayladı. O alan 2.400 pixel ve haftada 2.400 dolar — yani soru akademik değil. Kim alıyor, diğerine ne oluyor?
Cevap kısa: biri alanın tamamını alır, diğeri hiçbir bloğunu alamaz. İkisinin yarısını alması, ya da ikisinin birden alması mümkün değil. Bunun nasıl garanti edildiği, her pazar yerinin çözmek zorunda olduğu klasik bir problem.
"Önce bak, boşsa al" neden bozuk
Akla gelen ilk yöntem şu:
- Seçilen bloklar boş mu, kontrol et.
- Boşsa kiralamayı oluştur.
Bu, tek kullanıcı varken kusursuz çalışır. İki kullanıcı varken aradaki boşluk yüzünden çöker. Birinci adımla ikinci adım arasında geçen süre sıfır değil — mikrosaniyeler bile olsa bir süre var. İki istek o aralığa aynı anda girerse, ikisi de "boş" cevabını alır, ikisi de kiralamayı oluşturur. Kontrol doğruydu, sonuç yanlış.
Sinema salonu benzetmesi işi anlatıyor: koltuğun boş olduğunu görmek, o koltuğun senin olduğu anlamına gelmiyor. Bakmakla oturmak arasında geçen sürede biri oturabilir. Sistem "baktım, boştu" diye kayıt tutarsa iki kişiye aynı koltuğu satar.
Önemli olan şu: bu hata nadir olduğu için tehlikeli. Test ederken hiç görmezsin, gerçek trafikte ayda bir görürsün, ve gördüğünde elinde aynı alanı ödemiş iki kişi olur.
Çözüm: sabit ızgara ve bölünemez tek bir yazma
Çözümün ilk yarısı, tuvalin nasıl saklandığıyla ilgili. Blokları kiralandıkça oluşturmuyoruz. 10.000 bloğun tamamı zaten var — 100 × 100'lük ızgaranın her hücresi veritabanında duran bir satır. Fark şu: bir bloğun "boş" olması, o satırın yokluğu değil; satır orada, sadece sahibi yok.
Bu tek başına önemli bir fark. Olmayan bir şeyi iki kişinin aynı anda yaratmasını engellemek zordur. Var olan bir şeyin sahibini iki kişinin aynı anda değiştirmesini engellemek ise veritabanlarının zaten en iyi yaptığı iş.
Kontrol ile yazmayı tek işe indirmek
Çözümün ikinci yarısı, iki adımı tek adıma indirmek. Kiralama isteği veritabanına şöyle gitmiyor:
"Bu 24 blok boş mu? Boşsa bana yaz."
Şöyle gidiyor:
"Bu 24 bloğu, yalnızca hepsi sahipsizse, bana yaz."
Kontrol ile yazma artık ayrı iki iş değil, bölünemeyen tek bir iş. Aralarına başka bir isteğin sıkışabileceği bir boşluk yok, çünkü arada zaman yok.
İki istek aynı anda geldiğinde veritabanı bunları sıraya koyar. Birincisi çalışır, 24 bloğun hepsini sahiplenir. İkincisi çalışmaya başladığında koşul artık sağlanmıyor — bloklar sahipsiz değil — ve yazma hiç gerçekleşmeden reddedilir. Kaybedenin eline yarım bir kiralama geçmez, hiçbir şey geçmez.
Turnike benzetmesi daha doğru: kapı iki kişiyi aynı anda geçirmiyor, çünkü fiziksel olarak buna izin veren bir aralık yok. Kimin önce geldiğini turnike belirliyor ve diğeri kapalı kapı görüyor.
Neden "hepsi ya da hiçbiri"
Asıl sinsi durum tam örtüşme değil, kısmi örtüşme. Diyelim sen 6 × 4'lük bir alan istedin, başkası da seninkiyle 6 blokta kesişen başka bir alan istedi.
Blokları tek tek sahiplenen bir sistem burada yarım sonuç üretir: 18 blok sende, 6 blok onda kalır. İki taraf da kısmi alan sahibi olur, iki görsel de kendi alanına sığmayacağı için tuvalde iki bozuk dikdörtgen belirir. Bunu sonradan düzeltmek, para iadesi ve elle müdahale gerektiren bir karmaşadır.
Yazmanın bütün olması bu ihtimali ortadan kaldırıyor. Koşul "24 bloğun hepsi" diyor. 18'i boş, 6'sı dolu ise koşul sağlanmıyor ve hiçbir blok el değiştirmiyor. Sonuç ya tam ya da yok:
- Kazanan tam olarak istediği dikdörtgeni alır.
- Kaybeden hiçbir şey almaz, net bir hata görür, tuvalin güncel hali karşısına gelir ve komşu bir alan seçer.
Yarım kiralama diye bir durum yok, çünkü veritabanı seviyesinde böyle bir ara hâl tanımlı değil.
Sen görselini hazırlarken alanın duruyor mu
Buraya kadarki kısım, iki isteğin aynı anda çakışmasını çözüyor. Bir de daha yavaş bir yarış var: alanı seçtin, siparişi tamamlıyorsun, bu birkaç dakika sürüyor. Bu sırada başkası aynı alanı alabilir mi?
Alamaz. Alanı seçip işleme başladığın anda o bloklara bir tutma konuyor: bloklar başka birinin koşullu yazmasına takılacak şekilde işaretleniyor, yani başkasının aynı alan için gönderdiği istek reddediliyor.
Tutmanın ömrü sınırlı, çünkü olmasa terk edilmiş seçimler tuvali kilitlerdi. Birisi alanı seçip sekmeyi kapatırsa, süre dolduğunda bloklar kendiliğinden havuza döner. Aynı mantığın uzun vadeli hali de var: ödemesi yapılmış ama 30 gün içinde onaylanmış görseli olmayan bir sipariş iptal ediliyor, ödeme iade ediliyor ve alan serbest bırakılıyor. Amaç her iki durumda da aynı: hiç kullanılmayacak bir alanın süresiz kilitli kalmasını engellemek.
Bittikten sonraki tarafta da benzer bir kural işliyor. Kiralaman bittiğinde görsel tuvalden hemen kalkar ama bloklar 48 saat boyunca yalnızca senin yenileyebileceğin şekilde ayrılı kalır. Bu süre de bir tür tutma: yenileme kararını verirken kimsenin yerini kapmasını istemiyoruz. 48 saat dolduğunda alan herkese açılır.
Neden açık artırma değil de ilk gelen
Kural basit: bir alan havuzdaysa ilk kiralayan alır. Çakışmayı çözen mekanizma da bunun teknik karşılığından ibaret — turnikeden ilk geçen geçer.
Bu bilinçli bir tercih. Açık artırma ya da bekleme listesi eklemek, fiyatı açıklanamaz hale getirirdi. Şu anda fiyatı bilmek için hesap makinesine bile ihtiyacın yok: pixel sayısı kadar dolar, hafta sayısıyla çarp. Merkezdeki bir bloğun kenardaki bir bloktan pahalı olduğu bir düzende bu netlik kaybolur ve her kiralama bir pazarlığa dönüşür.
Bunun bir sonucu da şu: iyi bir yeri elde tutmanın tek yolu süresi dolmadan uzatmak. Uzatma mevcut bitiş tarihinin üstüne eklendiği için erken uzatmak sana hiçbir şey kaybettirmez, sadece yeri garantiye alır.
Rakam tarafı
Yarışın konusu olan alanın maliyetini net görelim. 6 × 4 blok = 60 × 40 pixel = 2.400 pixel.
- 1 hafta: 2.400 dolar
- 2 hafta: 4.800 dolar
- 4 hafta: 9.600 dolar
Kaybeden taraf için önemli olan şu: yazma hiç gerçekleşmediği için ortada bir kiralama oluşmuyor, dolayısıyla o alan adına bir borç da doğmuyor. Ödeme altyapısının şu anda test modunda çalıştığını da not edelim; gerçek ödeme entegrasyonu henüz devrede değil.
Çift kiralama, "dikkatli davranarak" önlenen bir şey değil; yapısal olarak imkânsız hale getirilmesi gereken bir şey. Sabit bir 10.000 satırlık ızgara ve bölünemeyen tek bir koşullu yazma bunu sağlıyor: istediğin blokların ya hepsini alırsın ya da hiçbirini. Aradaki dakikaları da tutma mekanizması koruyor.
Pratikte senin için anlamı basit: beğendiğin alanı gördüysen seçimi geciktirme, ama seçtikten sonra da telaşa kapılma — işlemi tamamlarken alan senin.