您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Postgres pg_try_advisory_lock阻止所有记录

Postgres pg_try_advisory_lock阻止所有记录

您正在对要扫描的整个集合中的每一行调用pg_try_advisory_lock()(作为在where子句中进行的过滤的一部分),而您只希望查询返回的table1中的每一行调用一次。

您可以尝试使用子查询或CTE代替:

with rows as (
SELECT a.id
FROM table1 a
JOIN table2 b ON a.table1_id = b.id
WHERE table2.id = 1
)
select rows.*
from rows
where pg_try_advisory_lock('table1'::regclass::integer, rows.id);

但是也不要依赖于它一定能按预期工作:Postgres应该试图以您的初始查询的方式重写它。

这是另一种可能性,因为select语句的一部分在查询中很晚才被求值:

with rows as (
SELECT a.id,
       pg_try_advisory_lock('table1'::regclass::integer, a.id) as locked
FROM table1 a
JOIN table2 b ON a.table1_id = b.id
WHERE table2.id = 1
)
select rows.id
from rows
where rows.locked;

实际上,真正的问题pg_try_advisory_lock()是您通常会在应用程序领域或函数中找到这些内容,而不是像您正在做的那样在查询中找到这些内容。说到哪个,取决于您在做什么,您确定不应该使用select… for update吗?

关于您的更新:

postgres扫描第一行然后停止?

是的。由于存在limit1,它将找到一个匹配项并立即停止。但是,可能发生的情况是,where根据查询的不同,它没有以相同的顺序评估该子句。sql不保证首先评估其中的a <>0部分a <> 0 and b / a > c。应用于您的案例,它不能保证 在a 的行与b联接 之后 获得咨询锁。

Postgres 2022/1/1 18:51:45 有484人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶