10

我认为关于 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

所以我想我的问题是,如何获得咨询锁以阻止它再次被获取?

4

2 回答 2

16

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

在文档中查看更多信息。

于 2012-04-23T14:57:46.017 回答
3

我对咨询锁的第一印象是相似的。我希望第二个查询 (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 作为参数允许更广泛的 id,但如果将其与“second_table”一起使用,则 id 17 也会被锁定(因为您锁定了数字“17”而不是与表中特定行的关系) .

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

于 2015-09-11T18:31:33.653 回答