rails 3 & activerecord: do I need to take special record locking precautions to update a counter field?

若如初见. 提交于 2019-12-21 06:56:07

问题


Each time a user's profile gets displayed we update an integer counter in the Users table.

I started thinking about high-concurrencey situations and wondered what happens if a bunch of people hit a user's profile page at the exact same time: does rails/activerecord magically handle the record locking and semaphore stuff for me?

Or does my app need to explicitly call some sort of mechanism to avoid missing update events when concurrent calls are made to my update method?

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

And along those lines, when should I use something like Users.increment_counter(:hit counter, self.id) instead?


回答1:


In the default configuration, a single Rails instance is only handling a single request at a time, so you don't have to worry about any concurrency trouble on the application layer.

If you have multiple instances of your application running (which you probably do/will), they will all make requests to the database without talking to one another about it. This is why this is handled at the database layer. MySQL, PostgreSQL, etc. are all going to lock the row on write.

The way you are handling this situation isn't ideal for performance though because your application is reading the value, incrementing it, and then writing it. That lag between read and write does allow for you to miss values. You can avoid this by pushing the increment responsibility to your database (UPDATE hitcounter SET hitcount = hitcount + 1;). I believe ActiveRecord has support for this built in, I'll/you'll have to go dig around for it though. Update: Oh, duh, yes you want to use the increment_counter method to do this. Reference/Documentation.

Once you update your process push incrementing responsibility to the database I wouldn't worry about performance for a while. I once had a PHP app do this once per request and it scaled gloriously for me to 100+ updates/second (mysqld on the same machine, no persistent connections, and always < 10% cpu).



来源:https://stackoverflow.com/questions/6313843/rails-3-activerecord-do-i-need-to-take-special-record-locking-precautions-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!