listen与notify
相关命令
PG提供了client端之间通过服务器端进行消息通信的机制。这种机制通过listen和notify命令完成
与listen和notify相关命令及函数:
*listen:监听消息通道
*unlisten:取消先前的监听
*notify:发送消息到消息通道中
*pg_notify():与notify命令功能相同,也可以发送消息到消息通道中
*pg_listening_channels():调用此函数可以查询当前session已注册了哪些消息监听
listen命令
listen channel
如果当前会话已经被注册为该消息通道的监听器,则再次执行listen,此消息通道的命令不会报错,相当于什么也不做
unlisten命令
注册消息监听后,如果不想再收到相应的消息,可以使用unlisten取消监听
unlisten {channel | *}
特殊的条件通配符“*”可以取消对当前会话所有监听的注册
notify命令
notify命令会发送一个通知事件,同时可以带一个可选的消息信息字符串到每个客户端应用程序,这些应用程序已经为当前数据库的指定名称通道预先执行了“listen channel”命令。如果上面的命令没有指定消息信息字符串,则消息信息字符串时空字符串
函数pg_notify()
可以使用函数pg_notify()发送通知事件
pg_notify(text,text)
第一个参数是消息通道的名称,第二个参数是要发送的消息信息字符串
函数pg_listening_channels()
调用函数pg_listening_channels()查询当前session注册的消息监听时
select pg_listening_channels();
使用注意
多个session可以同时监听同一个消息通道。当发送端发送一个消息时,所有监听者都可能收到此消息
如果在事务中调用notify发送消息,实际消息要在事务提交时才会被发送,如果事务回滚,消息将不会被发送
使用pg_notify函数也可以发送消息
如果在一个事务中发送两条消息的通道名称相同,消息字符串也完全相同,实际上只有一条消息被发送出去
notify能保证来自同一个事务的信息按照发送时的顺序交付,也能保证来自不同事务的信息按照事务提交的顺序交付
消息队列持有被发送但是未被监听会话处理的消息,这些消息太多会导致该队列变满,此时若调用notify命令会在提交时失败。但队列空间通常很大,在默认安装中是8GB,因此一般不会满。如果一个会话执行listen命令后,长时间处于一个事务中,不清理消息,可能导致队列变满
注意:在两阶段提交中不能使用notify命令