我目前正在玩弄交易,無法圍繞以下場景:爲什麼此事務在ActiveRecord中不起作用?
鑑於有用戶名「johnny」和全名「John Smith」。
我開始兩個軌道遊戲機和以該順序執行以下命令:
控制檯答:
ActiveRecord::Base.transaction { user = User.find_by_username("foo"); sleep 10; user.update_attribute(:full_name, "#{user.full_name}-1"); }
控制檯B:
ActiveRecord::Base.transaction { user = User.find_by_username("foo"); sleep 10; user.update_attribute(:full_name, "#{user.full_name}-2"); }
所以定時如下:
A讀「約翰史密斯」
B讀 「約翰·史密斯」
一個寫道: 「約翰·史密斯-1」
B進行讀寫 「約翰·史密斯-2」
根據我的數據庫類事務B應該不寫「約翰史密斯-2「,因爲數據讀取後發生了變化。所以交易應該回滾,交易A應該贏。我希望用戶名是「John Smith-1」,但結果是「John Smith-2」。
任何想法爲什麼發生這種情況或如何獲得預期的行爲?
親切的問候
尼爾斯
它可能是連接的隔離級別。確保樂觀鎖定而不是遊標穩定性。而且,具有諷刺意味的是,這可能是因爲交易。在技術上,如果兩個塊都在事務中,則第二個應該*開始*直到第一個完成,或者它應該遵循在ACID中定義的規則,第二個事務*好像*第一個沒有發生,但是提交* *第二個直到第一個完成纔開始。 –
是什麼讓你覺得這是activerecord特有的?如果從數據庫命令行界面執行類似的任務,結果是不同的? –
@FrederickCheung取決於你使用的SQL。如果它是'SELECT ... FOR UPDATE',那麼它會有所不同。仍然不是OP所期望的。但是,這將是悲觀的鎖定:http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html –