İki Sekme Nasıl Sessizce Birbirini Sildi: Concurrent Update Sorunu

Aynı ürünü iki tarayıcı sekmesinde açtığını düşün. Birinde fiyatı değiştirip kaydediyorsun, diğerinde açıklamayı düzenleyip kaydediyorsun. Kaydedikten sonra farkında olmadan ilk değişikliğin (fiyat) silinmiş olduğunu görüyorsun. Hata mesajı yok, başarısız istek yok. Sadece sessiz veri kaybı. Buna "lost update" deniyor ve Ahmed Mahmoud'un araştırması bu sorunu ve çözümünü adım adım açıklıyor.

Sorun şu: Veritabanı işlemleri (transaction) bu durumu engellemez. Çünkü iki farklı HTTP isteği var, birinci sekme okuyor, değiştiriyor, kaydediyor; ikinci sekme aynı kaydı okuyor (eski halini), değiştiriyor, kaydediyor. ORM'in varsayılan davranışı "son yazanın kazandığı" (last-write-wins) mantığıyla çalışır. İkinci istek tüm alanları geri gönderir, eski fiyat da dahil olmak üzere, ve bu eski değer veritabanında üzerini yazıyor.

Çözüm optimistic concurrency control: Kaydın bir sürüm numarası (version column) olur. Her güncellemede bu sürüm artar. İstemci (tarayıcı) bu sürümü ETag HTTP başlığı olarak alır ve geri gönderirken If-Match başlığında kontrol ettiriyor. Eğer sürüm eşleşmezse, yani başka biri arada değiştirmişse, UPDATE'in WHERE koşulu başarısız olur ve istek reddedilir. Kullanıcı açık bir çakışma hatası görür, sessiz veri kaybı değil.

Pratik olarak: Formunuz kaydedilmeden önce sunucu güncel sürümü kontrol eder. Eşleşmezse "Bu kayıt başka biri tarafından değiştirildi, lütfen yeniden yükle" diyebilirsiniz. Böylece iki sekme aynı anda çalışsa bile, hangisinin kaydedileceği kontrollü ve açık olur.

konu hakkında tepkinizi verebilirsiniz