pg_advisory_lock() 是一个用于获取独占会话级别的咨询锁的系统函数。
pg_advisory_lock() 在 PostgreSQL 8.2 中被添加。
用法
pg_advisory_lock (keybigint) →void
pg_advisory_lock (key1integer,key2integer) →void
pg_advisory_lock() 将无限期地等待以获取指定的锁。要获取锁,或者在锁不可用时立即返回,请使用 pg_try_advisory_lock()。
一旦获取到锁,它将在当前会话结束时,或者在执行 pg_advisory_unlock() 或 pg_advisory_unlock_all() 后被释放。
变更历史
- PostgreSQL 8.2
- 添加于(提交 9b4cda0d)
示例
pg_advisory_lock() 的基本用法示例
postgres=# SELECT pg_advisory_lock(123); pg_advisory_lock ------------------ (1 row)
此时将在 pg_locks 中有一个对应的条目
postgres=# SELECT locktype, database, objid, objsubid, mode, pid, granted, fastpath
FROM pg_locks
WHERE locktype = 'advisory';
locktype | database | objid | objsubid | mode | pid | granted | fastpath
----------+----------+-------+----------+---------------+---------+---------+----------
advisory | 5 | 123 | 1 | ExclusiveLock | 3787025 | t | f
(1 row)
从另一个会话尝试获取相同的锁会导致 pg_advisory_lock() 无限期地挂起
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3787428
(1 row)
Time: 0.367 ms
postgres=# SELECT pg_advisory_lock(123);
^CCancel request sent
ERROR: canceling statement due to user request
Time: 5385.386 ms (00:05.385)
如果持有锁的会话结束(在此示例中为第一个会话),则锁会被释放(即不再存在)
postgres=# \c - foo
You are now connected to database "postgres" as user "foo".
postgres=> SELECT pg_backend_pid();
pg_backend_pid
----------------
3787025
(1 row)
postgres=> SELECT locktype, database, objid, objsubid, mode, granted, fastpath
FROM pg_locks
WHERE locktype = 'advisory';
locktype | database | objid | objsubid | mode | granted | fastpath
----------+----------+-------+----------+------+---------+----------
(0 rows)
参考资料
- PostgreSQL 文档: 咨询锁函数
