Joh*_*hir 3 postgresql locking update
我想做这样的事情:
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;
Run Code Online (Sandbox Code Playgroud)
目标是避免两个进程同时执行 UPDATE 时出现死锁。此处详细描述了问题:Why am I get a deadlock for a single UPDATE query?
在我获取锁的语句中,我不需要有关行的任何信息。我只想锁定那些特定的行。有没有办法做到这一点(优雅或hacky),告诉postgres不要做任何实际给我数据的工作?
关于避免死锁的目标:请参阅我对相关问题的回答:
关于标题中的问题:
在子查询中使用带有锁定子句的SELECT
空(最短、最便宜)列表,并在外部运行:count()
SELECT
SELECT count(*) AS locked_rows
FROM (
SELECT FROM foos
WHERE owner_id = 123
AND unread
ORDER BY id
FOR UPDATE -- !
) sub;
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以获得包含锁定行数的单个结果行。在事务期间,子查询中选择的所有行都将被锁定。(如果有0
行,您可以中止。)
旁白:
and unread=true
只是一种吵闹的说法AND unread
。unread
可以的话NULL
,考虑unread IS NOT TRUE
一下。