轨道3及ActiveRecord的:我需要采取特殊的记录锁定precautions更新计数器字段? [英] rails 3 & activerecord: do I need to take special record locking precautions to update a counter field?

查看:107
本文介绍了轨道3及ActiveRecord的:我需要采取特殊的记录锁定precautions更新计数器字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当用户的个人资料被显示出来,我们更新了用户表中的整数计数器。

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

我开始思考高concurrencey的情况下,不知道会发生什么,如果一群人打一个用户的个人资料页面完全相同的时间:不导轨/ ActiveRecord的神奇处理记录锁定和信号灯的东西对我来说

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

和沿着这些线路,当我应该使用类似Users.increment_counter(:打反击,self.id)?而不是

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

推荐答案

在默认配置下,单个的Rails实例只处理一次单个请求,所以你不必担心对任何并发麻烦应用层。

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.

如果你有你的应用程序中运行的多个实例(你可能会做/会),他们都将发出请求到数据库,而互相交谈一下吧。这也就是为什么这是在数据库层处理。 MySQL和PostgreSQL等等都将锁定该行上写。

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.

正在处理这种情况的方法是不理想的业绩,但因为你的应用程序读取值,递增它,然后写它。读写之间的滞后确实允许你错过值。您可以通过推动增值责任,你的数据库避免这种情况(更新隐私权|发布SET hitcount = hitcount + 1; )。我相信的ActiveRecord已经支持这个建于,我会/你必须去周围挖了,但。 更新:的哦,真不错,是的,你要使用的 increment_counter 的方法来做到这一点。 参考/文档

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.

在您更新过程中推递增,责任到数据库中,我就不会担心了一段时间的表现。我曾经有每个请求的PHP应用程序,这样做一次,它光荣规模对我来说100+更新/秒(在同一台机器上的mysqld,没有持续连接,并始终小于10%的CPU)。

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).

这篇关于轨道3及ActiveRecord的:我需要采取特殊的记录锁定precautions更新计数器字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆