用途:LISTEN/NOTIFY 是 PostgreSQL 内置的发布-订阅通道,适合客户端之间做缓存失效、实时界面刷新、任务队列唤醒等无需定时轮询的场景;也可在 AFTER INSERT/UPDATE/DELETE 触发器中广播表变更。
基本用法:会话执行 LISTEN channel 订阅;任意会话执行 NOTIFY channel, 'payload' 或 pg_notify('channel','payload') 广播。取消订阅用 UNLISTEN channel 或 UNLISTEN *。动态频道名或载荷应使用 pg_notify(text,text),NOTIFY 要求字符串字面量。
关键约束:投递发生在 COMMIT,事务回滚不发通知;没有重放,未处于监听状态的客户端会永久错过事件;载荷是小于 8000 字节的字符串字面量,应只发主键而非整行。
规则与模式:始终用专用直连(或 session 模式)连接做监听会话,transaction 模式下 PgBouncer 会让 LISTEN 失效;始终把 NOTIFY 当作唤醒提示,若需保证送达,应配合持久队列表在每次唤醒后读取;载荷只放键,由监听方自行查询最新数据;不要在长事务中执行 LISTEN,否则会阻塞服务端通知队列清理。
适用场景:缓存失效、界面实时更新、任务队列低延迟唤醒、触发器捕获所有客户端(含手工 SQL)的写入变更。
限制:需要保证送达、可重放时不适合 LISTEN/NOTIFY 单独使用,应改用队列表(结合 SELECT ... FOR UPDATE SKIP LOCKED)或外部消息代理;跨库逻辑变更流应使用逻辑复制;跨进程协调应使用咨询锁。