pg 中的 Listen/Notify 是用来提供客户端之间通过服务段进行消息通信的机制。
listen:监听消息通道
unlisten:取消先前的监听
notify:发送消息到消息通道中
pg_notify():与 notify 命令的功能相同,也可以发送消息到消息同道中。
pg_listening_channels():调用此函数可以查询当前 session 已注册了哪些消息监听。
LISTEN channel (channel值任意)
用来注册一个消息通道。
如果在事务中执行 listen,那么事务必须成功 commit,listen才生效。
session 退出后 listen 自动释放。
NOTIFY channel [, payload] (payload默认要求小于8000字节, 且必须是常量) -- OR pg_notify(channel, payload)
用来往消息通道发送异步消息。
如果在事务中执行 notify,那么必须等事务成功 commit 之后这个消息才会塞进消息队列。
消息在事务和事务之间的间隙传递。因此如果有一个 listen 的 session 中跑了一个很长的事务,那么要等这个事务结束才能接收到这个过程中发出的 notify。
一个消息如果在发出 notify 之前有监听者,必须等这些监听者都接收到了这个消息才从消息队列中去除。
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;
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31490526/viewspace-2743682/,如需转载,请注明出处,否则将追究法律责任。