在 postgres 中获取咨询锁

问题描述 投票:0回答:2

我认为关于 postgres 中的咨询锁定,一定有一些我不理解的基本内容。如果我在 psql 命令行客户端上输入以下命令,该函数两次都会返回 true:

SELECT pg_try_advisory_lock(20); --> true
SELECT pg_try_advisory_lock(20); --> true

我期望第二个命令应该返回 false,因为锁应该已经被获取。奇怪的是,我确实得到了以下信息,表明锁已被获取两次:

SELECT pg_advisory_unlock(20); --> true
SELECT pg_advisory_unlock(20); --> true
SELECT pg_advisory_unlock(20); --> false

所以我想我的问题是,如何以一种阻止再次获取咨询锁的方式获取咨询锁?

postgresql locking
2个回答
17
投票

如果您尝试从 2 个不同的 PostgreSQL 会话执行此操作会怎样?

查看更多文档


4
投票

我对咨询锁的第一印象是相似的。我预计第二个查询(SELECT pg_tryadvisory_lock(20))也会返回 false(因为第一个查询获得了锁)。但此查询仅确认值为 20 的 bigInt 有锁。解释取决于用户。

将咨询锁想象为一个表,您可以在其中存储值并获取该值的锁(通常是 BigInt)。它没有显式锁定,并且不会延迟任何事务。这取决于您如何解释和使用结果 - 并且它不会阻塞。

我在我的项目中使用它的两个整数选项。 SELECT pg_try_advisory_lock(classId, objId) 而两个参数都是整数。

要使其与多个表一起使用,只需使用表的 OID 作为 classId 并将主 id(此处为 17)作为 objId:

SELECT pg_try_advisory_lock((SELECT 'first_table'::regclass::oid)::integer, 17);

在此示例中,“first_table”是表的名称,第二个整数是主键 ID(此处:17)。

使用 bigInt 作为参数(而不是如上所述的 2 个整数)允许更广泛的 id,但是如果将其与“second_table”一起使用,则 id 17 也会被锁定(因为您锁定了数字“17”并且不是与表中特定行的关系)。

我花了一些时间才弄清楚这一点,所以希望它有助于理解咨询锁的内部工作原理。

© www.soinside.com 2019 - 2024. All rights reserved.