Yaygın yanlış kullanım senaryoları: Kullanıcıların ödeme düğmesine yanlışlıkla birden fazla tıklaması nedeniyle siparişlerin tekrarlanan ödemelerini önlemek için, sipariş üzerinde işlemi yalnızca bir iş parçacığına yapmasına izin verilmesini sağlamak için kilitleme (sipariş numarası) kullanıyoruz.
Bu fikir iyidir, en azından sınıfları işlemek için özel statik bir nesne olan lock'dan daha iyidir, çünkü emir numarasını kilitlemenin etkisi sadece mevcut 1 siparişin işlemini kilitlemektir ve eğer statik değişkeni kilitlemek, yani tüm emirleri kilitlemek durumunda, tüm emirlerin sıraya girmesine neden olur ki bu açıkça mantıksızdır.
Peki, bu makalenin başında bahsedilen kilit (sipariş numarası) yöntemi istenen etkiyi elde edebilir mi? Önce kullanım senaryosunu geri yüklemek için biraz kod kullanalım.
Kullanıcı bilgilerini ve diğer doğrulamaları görmezden gelirseniz, kod neredeyse şöyle görünür:
Kilit anahtar kelimesi için MSDN, Baidu'da bulunabilen bilgileri içerir ve lock(string) kullanmamanın tavsiye edildiği anlaşılıyor, sebep aynı. Aşağıdaki bölüm, MSDN'nin kilitli iplerle ilgili tavsiyesinden alınmıştır:
Lock("myLock") sorunu, aynı diziyi kullanan diğer kodların aynı kilidi paylaşması nedeniyle ortaya çıkar. Bu cümle büyük bir mekanizmayı gizler, yani "aynı ip".
"Aynı ip" nedir? Koda bakınız:
Str1 ve str2 yukarıdaki aynı tel mi? Cevap EVET.
Tekrar bakınız:
Str1 ve str2 yukarıdaki hâlâ aynı tel mi? Cevap HAYIR.
Tamam, sipariş ödememiz meselesine geri dönelim. Kodumuzda, lock(orderNumber), kullanıcı elini kaydırdıktan sonra yanlışlıkla birkaç kez daha tıkladığında, bu eylemi giren orderNumber her seferinde aynı dizi mi? Cevap HAYIR. Yani
Yukarıdaki siparişi yöneten kod aslında kilit olarak işlemez.
Aslında, iki tür dizi karşılaştırması vardır, koda bakınız:
Yukarıdaki kodun ilk satırı Doğru, ikinci satır ise Yanlış çıktısını verir. MSDN'nin "aynı ip" dediğiyle ne demek istediğini benim açıklamam olmadan anladığınıza inanıyorum.
En iyi çözüm
Optimal kilitleme iplikleri için çözümler:
Demo kodu:
Web sitesinde bazen küresel bir değişken kullanılabilir, bu küresel değişken, birden fazla kullanıcı aynı anda eriştiğinde anormal görünebilir, bu zaman küresel bir kilitleme kuracağız, ancak dezavantajı tüm erişimlerin sırayla beklemesidir.
Örneğin, bazı durumlarda, aynı kullanıcı yalnızca 15 saniye içinde bir kez yorum yapabilir; küresel kilit kullanılırsa, kullanıcı sayısı arttığında yorum fonksiyonu çok yavaş işlemeye başlayacak ve bu da kullanıcı deneyimini büyük ölçüde etkiler.
Şu anda,Her kullanıcı için kilidi ayrı ayrı ayarlayabiliriz, lock(string){...} ve kilidin adı şu şekilde tanımlanabilir:Metet adı + kullanıcı kimliğiBu şekilde, her kullanıcının bağımsız bir kilidi olur ve yorum aralığı değerlendirildiğinde diğer kullanıcıların yorumlarını etkilemez.
(Son)
|