大佬教程收集整理的这篇文章主要介绍了sql – 将pg_try_advisory_xact_lock()放在嵌套的子查询中?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@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.
我应该在WHERE子句之外放置pg_try_advisory_lock()吗?怎么做?
让我先简化一下你的查询中的一些事情:
直接查询
updatE opportunities s SET opportunity_available = false FROM ( SELECT id FROM opportunities WHERE deal_id = #{@deal.iD} AND opportunity_available AND pg_try_advisory_xact_lock(id) LIMIT 1 FOR updatE ) sub WHERE s.id = sub.id RETURNING s.prize_id,s.id;
>所有双引号都只是你的合法,小写名称的噪音.
>由于opportunity_available是一个布尔列,您可以将opportunity_available = true简化为opportunity_available
>您不需要从子查询返回*,只需id即可.
通常,这是按原样工作的.说明如下.
避免对不相关的行进行咨询锁定
可以肯定的是,在下一个查询级别应用pg_try_advisory_xact_lock()之前,您可以使用OFFSET 0 hack(较少的开销)将所有谓词封装在CTE或子查询中:
updatE opportunities s SET opportunity_available = false FROM ( SELECT id FROM ( SELECT id FROM opportunities WHERE deal_id = #{@deal.iD} AND opportunity_available AND pg_try_advisory_xact_lock(id) OFFSET 0 ) sub1 WHERE pg_try_advisory_xact_lock(id) LIMIT 1 FOR updatE ) sub2 WHERE s.id = sub.id RETURNING s.prize_id,s.id;
但是,这通常要贵得多.
你可能不需要这个
如果您的查询基于涵盖所有谓词的索引(例如此部分索引),则不会有任何“附属”咨询锁定:
CREATE INDEX opportunities_deal_id ON opportunities (deal_id) WHERE opportunity_available;
检查EXPLAIN以验证POSTGRes实际使用索引.这样,pg_try_advisory_xact_lock(id)将成为索引或位图索引扫描的过滤条件,并且仅开始测试(和锁定)合格行,因此您可以使用简单形式而无需额外嵌套.同时,您的查询性能已得到优化.我会这样做的.
即使一些不相关的行应该偶尔得到一个咨询锁,这通常也无关紧要.咨询锁只与实际使用咨询锁的查询相关.或者你真的有其他并发事务也使用咨询锁并瞄准同一个表的其他行?真?
以上是大佬教程为你收集整理的sql – 将pg_try_advisory_xact_lock()放在嵌套的子查询中?全部内容,希望文章能够帮你解决sql – 将pg_try_advisory_xact_lock()放在嵌套的子查询中?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。