我想做这样的事情:
begin;
select * from foos where owner_id=123 and unread=true order by id for update;
update foos set unread=false where owner_id=123 and unread=true;
commit;
目标是在两个进程同时执行 UPDATE 时避免死锁。此处描述了更多问题:为什么我会遇到单个 UPDATE 查询的死锁?
在我获取锁的语句中,我不需要有关行的任何信息。我只想锁定那些特定的行。有没有办法做到这一点(优雅或hacky),它告诉postgres不要做任何实际给我数据的工作?
关于避免死锁的目标:请参阅我对您的相关问题的回答:
关于标题中的问题:
在子查询
SELECT
中使用带有锁定子句的空(最短、最便宜)列表,并count()
在外部运行SELECT
:这样,您将获得具有锁定行数的单个结果行。在事务期间,子查询中选择的所有行都被锁定。(如果有行,您可以中止
0
。)旁白:
and unread=true
只是一种吵闹的说法AND unread
。unread
可以NULL
,请考虑unread IS NOT TRUE
。