SuperAPI AI 工具集

postgres-impl-advisory-locks

数据与分析

查看项目

更新于 10-15 22:18

技能介绍

用途:该技能用于 PostgreSQL 咨询锁(advisory lock)的协作场景,例如跨多个应用实例确保定时任务至多执行一次、构建分布式互斥锁或临界区、协调队列 Worker、串行化无对应数据行的外部调用。咨询锁锁定的是应用自定义含义的整数键,而非行或表,服务端只保证同一排他键不会被两个会话同时持有;行为在 PostgreSQL 15、16、17 一致。

主要能力与选择原则:优先使用事务级锁 pg_advisory_xact_lock,事务结束(COMMIT、ROLLBACK 或崩溃)自动释放,不会泄漏;仅在受保护工作真正跨多个事务时才使用会话级 pg_advisory_lock,且必须配对 pg_advisory_unlock。需要立即根据结果决定时用 pg_try_advisory_lock / pg_try_advisory_xact_lock,返回布尔值。定时任务至多一次与“忙则跳过”必须使用 try 变体,否则阻塞锁会让各实例排队、任务顺序执行 N 次。多个子系统共享同一数据库时应使用双整数形式 pg_advisory_lock(classid, objid),classid 为子系统常量命名空间,objid 为资源 id;单 bigint 键空间与双 int4 键空间互不重叠。

使用方式:如定时任务示例 SELECT pg_try_advisory_lock(42, 1001); 获取 true 者执行并用 pg_advisory_unlock(42, 1001) 释放。分布式互斥可写 BEGIN; SELECT pg_advisory_xact_lock(hashtext('rebuild-search-index')); 执行临界区后 COMMIT。队列 Worker 应使用 SELECT ... FOR UPDATE SKIP LOCKED 认领行,仅有工作单元无对应行时才改用咨询锁。排查时查询 pg_locks 中 locktype='advisory' 的记录,objsubid=1 表示单键 bigint 锁,objsubid=2 表示双 int4 锁,granted=false 为等待者。

适用场景:跨实例定时任务、分布式互斥、队列协调、无行可锁的串行化操作、以及咨询锁卡住或经连接池异常的情况。

限制与反模式:不要用咨询锁替代行锁(保护具体行应使用 SELECT ... FOR UPDATE);会话级锁遗忘解锁会保留到连接关闭;ROLLBACK 不会释放会话级锁;在 SELECT ... LIMIT 中获取锁可能因 LIMIT 未先执行而产生悬挂锁;事务模式连接池会错误绑定后端。死锁诊断、查询性能分析、任务调度本身不属于本技能。具体函数签名与更多示例、反模式细节见资料所列 references 文件。