2012-01-18 15 views
1

基本上我有這個用戶模型具有一定的屬性說「健康」和另一模型,記錄所有用戶之間的鬥爭。用戶可以互相爭鬥,有些概率會決定誰勝出。兩人在戰鬥後都會失去生命。這是Rails 3中的競態條件問題嗎?

所以在戰役控制器, '創建' 動作我做了,

@battle = Battle.attempt current_user.id, opponent.id 

模型,

def self.attempt current_user.id, opponent_id 

    battle = Battle.new({:user_id => current_user.id, :opponent_id => opponent_id}) 

    # all the math calculation here 
    ... 

    # Update Health 
    ... 
    battle.User.health = new_health 
    battle.User.save 
    battle.save 

    return battle 

end 

回到控制器,我做...

new_user_health = current_user.health 

在戰鬥結束後獲得新的健康價值。然而,我得到的價值是舊的健康價值(戰前的健康價值)。

有沒有人在之前遇到過這種問題?


UPDATE

我行

new_user_health = current_user.health 

和工作前加

current_user.reload 

。問題解決了。謝謝!

+1

我_think_這是你正在面對的:http://stackoverflow.com/questions/5519741/how-can-i-know-when-to-refresh-my-model-object-in-rails – sarnold 2012-01-18 02:28:41

+0

哪部分令人困惑?雅這是實際的代碼,但我只突出主要的東西 – 2012-01-18 02:28:50

+0

我編輯代碼升技,現在不那麼混亂? – 2012-01-18 02:30:46

回答

4

看起來您正在獲得current_user,然後更新battle.user,然後預計current_user會自動更新值。這種類型的事情可以使用Rails'Identity Map,但是有一些注意事項需要先閱讀。

的問題是,即使兩個對象在數據庫中的相同數據的支持下,你必須在內存中的兩個對象。要刷新信息,您可以撥打current_user.reload

作爲一個側面說明,這不會因爲你不使用多個進程修改/讀取數據分類的競爭條件。在本例中,您正在讀取數據,然後更新內存中不同對象上的數據。如果您使用兩個線程同時訪問相同的信息,則可能會發生競態條件。

此外,你應該使用battle.user,而不是像韋恩在評論中提到的battle.User

+0

這就是我說的:)雖然你的時間更長。 (哦,如果我有鎳......)+1拼寫它全部。 – 2012-01-18 03:08:54