• PostgreSQL LISTEN 与NOTIFY命令


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

    1.1 LISTEN与NOTIFY的简单示例

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

    1. Last login: Wed Aug 31 09:49:07 2022 from 36.113.10.220
    2. [root@MaxwellDBA ~]# sudo -i -u maxwell
    3. [maxwell@MaxwellDBA ~]$ psql -d maxwelldb
    4. psql (12.9)
    5. Type "help" for help.
    6. maxwelldb=# listen maxwelldb;
    7. LISTEN
    8. maxwelldb=#

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

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

    1. Last login: Wed Aug 31 09:49:07 2022 from 36.113.10.220
    2. [root@MaxwellDBA ~]# sudo -i -u maxwell
    3. [maxwell@MaxwellDBA ~]$ psql -d maxwelldb
    4. psql (12.9)
    5. Type "help" for help.
    6. maxwelldb=# notify maxwelldb,'hello world';
    7. NOTIFY
    8. maxwelldb=#

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

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

    1. maxwelldb=# select 1;
    2. ?column?
    3. ----------
    4. 1
    5. (1 row)
    6. Asynchronous notification "maxwelldb" with payload "hello world" received from server process with PID 348285.
    7. 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注册的消息监听,命令如下:

    1. maxwelldb=# listen maxwelldb1;
    2. LISTEN
    3. maxwelldb=# listen maxwelldb2;
    4. LISTEN
    5. maxwelldb=# select pg_listening_channels();
    6. pg_listening_channels
    7. -----------------------
    8. maxwelldb1
    9. maxwelldb2
    10. (2 rows)
    11. maxwelldb=#

    1.3 LISTEN与NOTIFY的使用详解

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

    1. [maxwell@MaxwellDBA ~]$ psql -d maxwelldb
    2. psql (12.9)
    3. Type "help" for help.
    4. maxwelldb=# listen maxwelldb;
    5. LISTEN

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

    1. [maxwell@MaxwellDBA ~]$ psql -d maxwelldb
    2. psql (12.9)
    3. Type "help" for help.
    4. maxwelldb=# listen maxwelldb;
    5. LISTEN
    6. maxwelldb=#

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

    1. [root@MaxwellDBA ~]# sudo -i -u maxwell
    2. [maxwell@MaxwellDBA ~]$ psql -d maxwelldb
    3. psql (12.9)
    4. Type "help" for help.
    5. maxwelldb=# notify maxwelldb,'hello world1';
    6. NOTIFY
    7. maxwelldb=# notify maxwelldb,'hello world2';
    8. NOTIFY
    9. maxwelldb=#

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

    1. maxwelldb=# select 1;
    2. ?column?
    3. ----------
    4. 1
    5. (1 row)
    6. Asynchronous notification "maxwelldb" with payload "hello world1" received from server process with PID 348432.
    7. Asynchronous notification "maxwelldb" with payload "hello world2" received from server process with PID 348432.
    8. maxwelldb=#

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

    1. maxwelldb=# select 1;
    2. ?column?
    3. ----------
    4. 1
    5. (1 row)
    6. Asynchronous notification "maxwelldb" with payload "hello world1" received from server process with PID 348432.
    7. Asynchronous notification "maxwelldb" with payload "hello world2" received from server process with PID 348432.
    8. maxwelldb=#

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

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

  • 相关阅读:
    前端框架 Nextjs 实现React SEO优化
    Java进阶知识点及案例总结(续2)
    kubeadm系列-02-kubelet的配置和启动
    SpringMvc(2)RequestMapping注解
    2023计算机毕业设计SSM最新选题之java乡村疫情防控管理系统37804
    visual studio code中base环境切换的问题
    分析常见限流算法及手写三种(计数器、漏斗、令牌桶)代码实现
    【机器学习】Tensorflow.js:我在浏览器中使用机器学习实现了图像分类
    如何针对结构化文本查询修改记录
    vue3的抽离封装方法
  • 原文地址:https://blog.csdn.net/u011868279/article/details/126621383