当前位置: 首页 > news >正文

PostgreSQL LISTEN 与NOTIFY命令

PostgreSQL提供了client端和其他client端通过服务器端进行消息通信的机制。这种机制是通过LISTEN和NOTIFY命令来完成的。

1.1 LISTEN与NOTIFY的简单示例

先运行一个psql(这里称为“session1”),执行LISTEN命令,示例如下:

Last login: Wed Aug 31 09:49:07 2022 from 36.113.10.220
[root@MaxwellDBA ~]# sudo -i -u maxwell
[maxwell@MaxwellDBA ~]$ psql -d maxwelldb
psql (12.9)
Type "help" for help.

maxwelldb=# listen maxwelldb;
LISTEN
maxwelldb=#

上面的命令“listen maxwelldb”中的“maxwelldb”是一个消息通道名称,实际上也可以是其他任何字符串。

再运行另一个psql(这里称为“session2”),执行NOTIFY命令,示例如下:

Last login: Wed Aug 31 09:49:07 2022 from 36.113.10.220
[root@MaxwellDBA ~]# sudo -i -u maxwell
[maxwell@MaxwellDBA ~]$ psql -d maxwelldb
psql (12.9)
Type "help" for help.

maxwelldb=# notify maxwelldb,'hello world';
NOTIFY
maxwelldb=# 

NOTIFY命令后的消息通道名称要与前面的LISTEN命令后的消息通道名称一致。

此时,session1还没有反应,在session1上随便运行一条命令,示例如下:

maxwelldb=# select 1;
 ?column? 
----------
        1
(1 row)

Asynchronous notification "maxwelldb" with payload "hello world" received from server process with PID 348285.
maxwelldb=# 

可以看到最后一行显示收到一个异步消息“Asynchronous notification "osdba" with payload "hello world".

1.2 LISTEN与NOTIFY的相关命令

LISTEN与NOTIFY的相关命令及函数主要有以下几个。

·LISTEN:监听消息通道。

·UNLISTEN:取消先前的监听。

·NOTIFY:发送消息到消息通道中。

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

·pg_listening_channels():调用此函数可以查询当前session已注册了哪些消息监听。下面讲解每个命令的用法。先看LISTEN命令,示例如下:

LISTEN channel

此命令比较简单,后面跟一个通道名称。如果当前会话已经被注册为该消息通道的监听器,再次执行LISTEN命令,此消息通道的命令不会报错,相当于什么也不做。

注册消息监听后,如果不想再收到相应的消息,可以使用UNLISTEN命令取消监听,UNLISTEN命令的语法格式如下:

UNLISTEN { channel | * }

使用特殊的条件通配符“*”可以取消对当前会话所有监听的注册。

下面介绍NOTIFY命令,示例如下:NOTIFY channel [ ,' payload' ]NOTIFY命令发送一个通知事件,同时可以带一个可选的消息信息字符串到每个客户端应用程序,这些应用程序已经预先为当前数据库的指定名称的通道执行LISTEN channel命令。如果上面的命令没有指定消息信息字符串,则消息信息字符串是空字符串。也可以使用函数pg_notify()来发送通知事件,此函数的语法格式如下:pg_notify(text, text)第一个参数是消息通道的名称,第二个参数是要发送的消息信息字符串。调用函数pg_listening_channels()查询当前session注册的消息监听,命令如下:

maxwelldb=# listen maxwelldb1;
LISTEN
maxwelldb=# listen maxwelldb2;
LISTEN
maxwelldb=# select pg_listening_channels();
 pg_listening_channels 
-----------------------
 maxwelldb1
 maxwelldb2
(2 rows)

maxwelldb=#

1.3 LISTEN与NOTIFY的使用详解

多个session可以同时监听同一个消息通道。当发送端发送一个消息时,所有监听者都可能收到此消息。示例如下。先运行一个psql(这里称为“session1”),执行LISTEN命令,命令如下:

[maxwell@MaxwellDBA ~]$ psql -d maxwelldb
psql (12.9)
Type "help" for help.

maxwelldb=# listen maxwelldb;
LISTEN

再运行另一个psql(这里称为“session2”),执行LISTEN命令,命令如下:

[maxwell@MaxwellDBA ~]$ psql -d maxwelldb
psql (12.9)
Type "help" for help.

maxwelldb=# listen maxwelldb;
LISTEN
maxwelldb=#

运行另一个psql(这里称为“session3”),执行NOTIFY命令,命令如下:

[root@MaxwellDBA ~]# sudo -i -u maxwell
[maxwell@MaxwellDBA ~]$ psql -d maxwelldb
psql (12.9)
Type "help" for help.

maxwelldb=# notify maxwelldb,'hello world1';
NOTIFY
maxwelldb=# notify maxwelldb,'hello world2';
NOTIFY
maxwelldb=#

这时,在session1上随便运行一条命令,命令如下:

maxwelldb=# select 1;
 ?column? 
----------
        1
(1 row)

Asynchronous notification "maxwelldb" with payload "hello world1" received from server process with PID 348432.
Asynchronous notification "maxwelldb" with payload "hello world2" received from server process with PID 348432.
maxwelldb=#

在session2上随便运行一条命令,命令如下:

maxwelldb=# select 1;
 ?column? 
----------
        1
(1 row)

Asynchronous notification "maxwelldb" with payload "hello world1" received from server process with PID 348432.
Asynchronous notification "maxwelldb" with payload "hello world2" received from server process with PID 348432.
maxwelldb=# 

从上面的运行结果中可以看到session1和session2都可以接收到此消息。

如果在事务中调用NOTIFY发送消息,实际上消息在事务提交时才会被发送,如果事务回滚了,消息将不会被发送,示例如下。

相关文章:

  • 基于ssm的养老智慧服务平台毕业设计源码071526
  • MySQL 安装详细步骤
  • 关于 SAP ABAP CL_HTTP_CLIENT API 中的 SSL_ID 参数
  • JavaFX、贷款服务器
  • Powershell历史执行记录
  • elementui中表格组件的高度修改没效果
  • 难受啊,早饭忘记吃了
  • 标签上有什么defer和async属性?<script>
  • 放大器的稳定性分析举例
  • ipsec vxn详解
  • Redis实战:保证数据不丢失,RDBAOF持久化原理解析
  • 总共300万嘞,成都市武侯区关于促进电子商务发展的若干政策出来了
  • Linux·设备文件devfs
  • MySQL in和exists 查询分析
  • 使用easyui-treegrid数据层级展示问题
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • const let
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Git的一些常用操作
  • JS笔记四:作用域、变量(函数)提升
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • 初识 beanstalkd
  • 近期前端发展计划
  • 马上搞懂 GeoJSON
  • 扑朔迷离的属性和特性【彻底弄清】
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • $(selector).each()和$.each()的区别
  • ${factoryList }后面有空格不影响
  • (11)MATLAB PCA+SVM 人脸识别
  • (6)添加vue-cookie
  • (C语言)fgets与fputs函数详解
  • (Python) SOAP Web Service (HTTP POST)
  • (Ruby)Ubuntu12.04安装Rails环境
  • (分布式缓存)Redis哨兵
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (转)VC++中ondraw在什么时候调用的
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • *p++,*(p++),*++p,(*p)++区别?
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .Net中的集合
  • .ui文件相关
  • ::什么意思
  • ??eclipse的安装配置问题!??
  • @SentinelResource详解
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [].slice.call()将类数组转化为真正的数组
  • [383] 赎金信 js
  • [AIR] NativeExtension在IOS下的开发实例 --- IOS项目的创建 (一)
  • [Android View] 可绘制形状 (Shape Xml)
  • [BUG] Authentication Error