PostgreSQL:LISTEN | NOTIFY

来源:这里教程网 时间:2026-03-14 20:14:42 作者:

pg 中的 Listen/Notify 是用来提供客户端之间通过服务段进行消息通信的机制。

listen:监听消息通道

unlisten:取消先前的监听

notify:发送消息到消息通道中

pg_notify():与 notify 命令的功能相同,也可以发送消息到消息同道中。

pg_listening_channels():调用此函数可以查询当前 session 已注册了哪些消息监听。

LISTEN

LISTEN channel (channel值任意)

用来注册一个消息通道。

如果在事务中执行 listen,那么事务必须成功 commit,listen才生效。

session 退出后 listen 自动释放。

NOTIFY

NOTIFY channel [, payload] (payload默认要求小于8000字节, 且必须是常量)
  
-- OR
pg_notify(channel, payload)

用来往消息通道发送异步消息。

如果在事务中执行 notify,那么必须等事务成功 commit 之后这个消息才会塞进消息队列。

消息在事务和事务之间的间隙传递。因此如果有一个 listen 的 session 中跑了一个很长的事务,那么要等这个事务结束才能接收到这个过程中发出的 notify。

一个消息如果在发出 notify 之前有监听者,必须等这些监听者都接收到了这个消息才从消息队列中去除。

UNLISTEN

UNLISTEN { channel | *)}

注册消息监听后,如果不想再收到相应的消息,可以使用 UNLISTEN 取消监听。UNLISTEN * 可以取消所有监听的注册,在会话结束是也会自动执行这个命令。

示例

通用场景

多个 session 可以同时监听同一个消息通道。当发送端发送一个消息时,所有监听者都可能收到此消息。

-- session 1
postgresql > listen test
 
-- session 2
postgresql > listen test
 
-- session 3
postgresql > notify test, 'hello world';
 
-- session 1
postgresql > select 1;
 
-- session 2
postgresql > select 1;

回滚场景

如果在事务中调用 notify 发送消息,实际消息要在事务提交时才会被发送,如果事务回滚了,消息将不会发送

-- session 1
postgresql > listen test
 
-- session 2
postgresql > begin;
postgresql > notify test, 'hello world';
 
-- session 1
postgresql > select 1;
 
-- session 2
postgresql > begin;
postgresql > notify test, 'hello world';
postgresql > end;
 
-- session 1
postgresql > select 1;

相同消息

如果在一个事务中发送两条消息的通道名称相同,消息字符串也完全相同,则实际上只有一条消息发送出去

-- session 1
postgresql > listen test
 
-- session 2
postgresql > notify test, 'hello world1';
postgresql > notify test, 'hello world1';
postgresql > notify test, 'hello world2';
 
-- session 1
postgresql > select 1;

相关推荐