【发布时间】:2015-10-14 14:45:01
【问题描述】:
在我的 Ruby on Rails 4 应用程序中,我对 Postgres 9.4 数据库进行了以下查询:
@chosen_opportunity = Opportunity.find_by_sql(
" UPDATE \"opportunities\" s
SET opportunity_available = false
FROM (
SELECT \"opportunities\".*
FROM \"opportunities\"
WHERE ( deal_id = #{@deal.id}
AND opportunity_available = true
AND pg_try_advisory_xact_lock(id) )
LIMIT 1
FOR UPDATE
) sub
WHERE s.id = sub.id
RETURNING sub.prize_id, sub.id"
)
非常受this related answer on dba.SE的启发。
但是在这里 (Postgres pg_try_advisory_lock blocks all records) 他们说,如果我没记错的话,我不应该在 WHERE 子句中使用 pg_try_advisory_lock(),因为我会称它为 在被扫描的整个集合中每行一次(作为 where 子句中发生的过滤的一部分)。
我只想让我的查询找到并更新第一行(随机,LIMIT)available = true 并将其更新为available = false,我需要在执行此操作时锁定该行,但不创建新行请求等待释放前一个锁,所以我添加了咨询锁like suggested here。
我应该将pg_try_advisory_lock() 放在WHERE 子句之外吗?怎么做?
【问题讨论】:
-
@patrick,没有其他问题 (stackoverflow.com/questions/33129132/…) 是关于相同的查询,但主题不同:我应该使用 pg_try_advisory_lock 还是 NOWAIT 选项?同一代码上的完全不同的问题。
-
@patrick,或者纯属巧合,因为我是 postgresql 菜鸟,NOWAIT 是当前问题的答案?
标签: sql ruby-on-rails ruby-on-rails-3 postgresql concurrency