You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于libpqxx派生类实现PostgreSQL事件监听?

解决libpqxx监听PostgreSQL触发器事件的抽象类派生问题

pqxx::notification_receiver是抽象基类,包含纯虚函数operator(),必须通过自定义派生类实现该函数才能完成通知监听逻辑。以下是具体实现步骤和完整代码:

1. 定义自定义通知接收器

创建派生类继承pqxx::notification_receiver,重写operator()函数——这个函数会在PostgreSQL发送通知时被自动调用,用于处理通知内容。

2. 修正监听逻辑

不需要用conn.prepare()处理LISTEN命令,直接执行exec("LISTEN my_event")完成监听注册,再通过连接对象的等待方法阻塞或轮询通知。

完整示例代码:

#include <pqxx/pqxx>
#include <iostream>

// 自定义通知接收器,继承抽象基类
class MyNotificationReceiver : public pqxx::notification_receiver
{
public:
    // 构造函数:传递连接对象和监听通道名给基类
    MyNotificationReceiver(pqxx::connection &conn, const std::string &channel)
        : pqxx::notification_receiver(conn, channel) {}

    // 重写纯虚函数,处理收到的通知
    void operator()(const std::string &channel, const std::string &payload, int backend_pid) override
    {
        std::cout << "收到通知:" << std::endl;
        std::cout << "通道名:" << channel << std::endl;
        std::cout << "通知内容:" << payload << std::endl;
        std::cout << "后端进程PID:" << backend_pid << std::endl;
    }
};

int main()
{
    try
    {
        // 建立数据库连接,替换为你的数据库参数
        pqxx::connection conn("dbname=your_db user=your_user password=your_pass hostaddr=127.0.0.1 port=5432");
        if (!conn.is_open())
        {
            std::cerr << "无法连接数据库" << std::endl;
            return 1;
        }

        // 创建自定义接收器实例
        MyNotificationReceiver receiver(conn, "my_event");

        // 注册监听通道
        conn.exec("LISTEN my_event");
        std::cout << "开始监听通道my_event..." << std::endl;

        // 循环等待通知
        while (true)
        {
            // 阻塞等待通知,可指定超时时间(单位:毫秒)
            if (conn.wait_for_notification(5000))
            {
                std::cout << "------------------------" << std::endl;
            }
            else
            {
                std::cout << "等待超时,继续监听..." << std::endl;
            }
        }

        conn.disconnect();
    }
    catch (const std::exception &e)
    {
        std::cerr << "错误:" << e.what() << std::endl;
        return 1;
    }

    return 0;
}

关键说明

  • operator()的三个参数分别对应:通知通道名、触发器发送的自定义负载内容(需在触发器中用NOTIFY my_event, '自定义内容'指定)、发送通知的PostgreSQL后端进程PID。
  • wait_for_notification()可指定超时时间,避免无限阻塞;若不填参数,会一直阻塞直到收到通知。
  • 确保触发器正确发送通知,示例触发器SQL:
    CREATE OR REPLACE FUNCTION trigger_notify()
    RETURNS TRIGGER AS $$
    BEGIN
        NOTIFY my_event, '目标表已完成更新';
        RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    
    CREATE TRIGGER table_update_trigger
    AFTER UPDATE ON your_target_table
    FOR EACH ROW EXECUTE FUNCTION trigger_notify();
    

内容的提问来源于stack exchange,提问作者shashashamti2008

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:51:13