Şu an işlemlerle uğraşıyorum ve şu senaryoyu taklit edemiyorum:Bu işlem neden ActiveRecord'da çalışmıyor?
Kullanıcı adı "johnny" ve tam adı "John Smith" olduğu düşünüldüğünde.
iki ray konsolları başlayıp bu sırada aşağıdaki komutları uygulayın:
Konsol A:
ActiveRecord::Base.transaction { user = User.find_by_username("foo"); sleep 10; user.update_attribute(:full_name, "#{user.full_name}-1"); }
Konsol B:
ActiveRecord::Base.transaction { user = User.find_by_username("foo"); sleep 10; user.update_attribute(:full_name, "#{user.full_name}-2"); }
Yani zamanlama şudur:
A okuru "John Smith"
B "John Smith"
bir yazar okur "John Smith-1"
B "John yazmaya başarısız olması benim veritabanı sınıfı işlem B'ye göre, "John Smith-2"
yazıyor Smith-2 "çünkü okuduğundan beri veriler değişti. Böylece işlem geri alınmalı ve A işlemi kazanmalıdır. Kullanıcı adının "John Smith-1" olmasını bekliyorum, ancak sonuç "John Smith-2".
Bunun neden olduğu veya beklenen davranışı nasıl alacağına dair herhangi bir fikir var mı? Ben işlem kilitleme ilgili değil anladığım kadarıyla
Tür Bildiğim kadarıyla
Nils
Bağlantının yalıtım düzeyi olabilir. İyimser kilitleme ve imleç kararlılığı olmadığından emin olun. Ayrıca, ironik olarak, işlem yüzünden olabilir. Her iki blok da bir işlem içerisindeyse, teknik olarak, ikincinin ilk bitirene kadar * başlaması * ya da ikinci işlemin * ikinci işlemin * sanki ilk olmamış gibi davranması gerekir. * ikincisi ilk bitene kadar başlamadı. –
Bunun harekete geçirici olduğunu düşündüğünüz nedir?Veritabanı komut satırından benzer bir görev gerçekleştirirseniz arabirim farklı sonuç mu? –
@FrederickCheung Kullandığınız SQL'e bağlıdır. Eğer 'SELECT ... UPDATE İÇİN' ise, o zaman farklı olurdu. Hala OP'nin beklediği değil. Ama sonra kötümser bir kilitlenme olurdu: http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html –