编写一个查询,如果目标行上有锁,该查询将退出

Con*_*bil 2 postgresql locking update query-performance

是否可以编写一个UPDATE查询,如果它尝试更改的记录被另一个进程锁定(而不是等待锁被释放),则该查询将简单地退出?

我有一个进程应该更新表中的记录,有时这些记录会被锁定。更新这些记录是可取的,但不是必需的。如果记录正在使用中,我宁愿我的流程忘记更新并继续处理更重要的事情。

我当前的方法是将命令超时设置为 1 秒,但即使这也比我想要等待的时间长 - 正常更新需要不到一毫秒,因此等待一秒是一个主要开销。

Erw*_*ter 5

SKIP LOCKED可能会为您提供最好的服务。

UPDATE tbl
SET    unimportant_column = 'foo'
WHERE  tbl_id = (
         SELECT tbl_id
         FROM   tbl
         WHERE  tbl_id = 3  -- filtering a single row
         FOR    UPDATE SKIP LOCKED
         );
Run Code Online (Sandbox Code Playgroud)

手册:

要防止操作等待其他事务提交,请使用NOWAITSKIP LOCKED选项。使用 时NOWAIT,如果无法立即锁定所选行,则该语句将报告错误,而不是等待。使用 时SKIP LOCKED,将跳过任何无法立即锁定的选定行。

在您的情况下,SELECT过滤器恰好是一行。如果它被锁定,它将被跳过,并且什么也不会发生。

与 的本质区别是NOWAIT:不会引发错误,而是默默地跳过该操作。这可能最适合您的情况。

您还可以通过这种方式更新多行(使用IN代替=)。任何锁定的行都将被跳过,其余行将被更新。有了NO WAIT,整个过程UPDATE就会被引发的错误所阻止。(除非您捕获异常,否则整个事务都会回滚。)

有关的: