PostgreSQL LISTEN/NOTIFY不起作用

3
以下是基本设置:
  • 一个PHP脚本将数据写入数据库表,并发出 NOTIFY job_added 。然后它开始通过发出 LISTEN job_complete 来等待响应。

  • 守护程序(用C语言编写)已经发出了 LISTEN jod_added ,因此会被唤醒并处理该表。

  • 守护进程处理表格并将结果写入结果表中,然后调用 NOTIFY job_complete

  • 然后PHP脚本被唤醒并从结果表中检索结果。

除了最后一步之外,其他都正常工作。守护进程使用libpq,我已经检查了守护进程添加完结果到结果表后发出的 NOTIFY 的成功情况。
因此,我认为问题在于PHP脚本。以下是相关代码:
$id = query("INSERT into jobs_table (/* details not important */) VALUES (/* */) RETURNING id");

query("NOTIFY job_added");
//daemon wakes up and does its thing.

query("LISTEN job_complete".$id);

$time = time();
while((time() - $time) < 30) {
    $notify = pg_get_notify($conn);
    if($notify) {
        // Never gets here
        if($notify['message']=="job_complete".$id) {
            //our job has completed
            break;
        }
    }
    usleep(25000);
}

所以我们向jobs表中添加内容,发出一个LISTEN命令,并循环30秒直到收到通知表示我们的任务已经完成。
问题在于pg_get_notify()永远无法获取守护程序发出的NOTIFY。请注意,守护程序发出的NOTIFY是在php脚本进行LISTEN操作之后发生的,我已经检查过了。
我有没有做错什么?顺便说一下,我非常清楚query()不是内置函数,只是为了简洁而添加的。
谢谢。

你可能想使用 sleepusleep 或者 time_sleep_until 来代替循环直到时间结束的方法。 - Charles
也许你正在通知“job_complete”,而不是“job_complete”。$id? - Brian L
brian-l:恐怕不行。在守护进程中,我基本上是这样做的:snprintf(buf, sizeof(buf), "NOTIFY job_complete%d", job_id);,然后从libpq调用PQexec(conn, buf); - tbh1
3
问题已解决。我之前并没有将连接句柄传递给 pg_get_notify,而是传递了一个数据库对象(针对自定义类)。我真是太傻了!请原谅。 - tbh1
6
你可以考虑将这个内容发布为答案,以备将来参考。 - user330315
1个回答

3
我愿意打赌,问题可能是您没有提交事务。提交时会引发通知。

尝试:

 query('COMMIT');

看看这是否能为您引起通知。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接