ruby-on-rails - ActiveRecord/Rails 中的原子插入或增量

标签 ruby-on-rails ruby-on-rails-3 rails-activerecord

在 Rails 中为带有计数器的模型实现原子插入/更新的最佳方法是什么?对于我试图解决的问题,一个很好的类比是带有两个字段的“like”计数器:

url   : string
count : integer

插入时,如果当前没有匹配 url 的记录,则应创建一条新记录,计数为 1;否则现有记录的 count 字段应增加。

最初我尝试了如下代码:

Like.find_or_create_by_url("http://example.com").increment!(:count)

但毫不奇怪,生成的 SQL 显示 SELECT 发生在 UPDATE 事务之外:

Like Load (0.4ms)  SELECT `likes`.* FROM `likes` WHERE `likes`.`url` = 'http://example.com' LIMIT 1
(0.1ms)  BEGIN
(0.2ms)  UPDATE `likes` SET `count` = 4, `updated_at` = '2013-01-17 19:41:22' WHERE `likes`.`id` = 2
(1.6ms)  COMMIT

是否有 Rails 习惯用法来处理这个问题,或者我是否需要在 SQL 级别实现它(从而失去一些可移植性)?

最佳答案

您可以使用pessimistic locking ,

like = Like.find_or_create_by_url("http://example.com")
like.with_lock do
    like.increment!(:count)
end

关于ruby-on-rails - ActiveRecord/Rails 中的原子插入或增量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14387022/

相关文章:

ruby-on-rails - 在 ubuntu 上安装 Ruby on Rails 失败。我能有帮助吗?

javascript - 使用JS/jQuery返回原文

ruby-on-rails-3 - 多对多关系的事件记录查询

ruby-on-rails - 如何使用 Postgres 在 Rails 5.2 中设置日期的默认值?

ruby-on-rails - Rails 中的多个提交按钮/表单

ruby-on-rails - learn-rails bundle 安装解析 Gemfile 时出错

ajax - 如何检查我的 Rails Controller 需要什么 csrf token ?

ruby-on-rails - 如何在 rails 3 中进行自定义 mySQL 查询?

ruby-on-rails - 具有组合属性的 Rails 作用域

ruby-on-rails - 我认为这个查询是错误的吗?