2011-06-11 58 views
1

每次用戶的配置文件顯示時,我們都會更新Users表中的整數計數器。rails 3&activerecord:我需要採取特殊記錄鎖定預防措施來更新計數器字段嗎?

我開始考慮高併發情況,並想知道如果一堆人在同一時間點擊用戶的個人資料頁會發生什麼情況:rails/activerecord是否會爲我處理記錄鎖定和信號量?

或者,我的應用程序是否需要顯式調用某種機制以避免在對我的更新方法進行併發調用時丟失更新事件?

def profile_was_hit 
    self.update_attributes :hitcounter => self.hitcount + 1 
end 

並沿着這些線路,當我應該使用類似Users.increment_counter(:打反擊,self.id)呢?

回答

4

在默認配置中,單個Rails實例一次只處理一個請求,因此您不必擔心應用程序層出現任何併發問題。

如果您有多個應用程序正在運行(您可能會/將會),它們都會向數據庫發出請求,而不會彼此交談。這就是爲什麼這是在數據庫層處理。 MySQL,PostgreSQL等都將在寫入時鎖定該行。

您處理這種情況的方式對性能並不理想,因爲您的應用程序正在讀取值,增加值並寫入。讀取和寫入之間的延遲確實會讓您錯過值。您可以通過將增量責任推送到數據庫來避免這種情況(UPDATE hitcounter SET hitcount = hitcount + 1;)。我相信ActiveRecord已經支持這個內置,我/你將不得不去尋找它。 更新:哦,是的,是的,你想用increment_counter方法來做到這一點。 Reference/Documentation

一旦你更新你的流程推送遞增責任到數據庫,我不會擔心一段時間的性能。我曾經有一個PHP應用程序每次請求執行一次這樣的操作,並且它對我的升級速度達到100+次更新/秒(同一臺機器上的mysqld,沒有持久連接,並且始終爲< 10%cpu)。

+0

非常感謝您的幫助。這應該有助於很多人。所以nmy外賣是使用increment_counter的原因是將它推送到dbase層,所以在多實例環境中(我在heroku上)它管理不同的實例同時更新。謝謝! – jpwynn 2011-06-11 17:20:07

相關問題