问题:
我已经设置了一个PostgreSQL函数和触发器,当RiderDataPosition
表上有INSERT
、UPDATE
或DELETE
操作时发送通知。然而,尽管我努力了,我还是没有收到任何预期的通知。我正在寻求解决此问题的指导。我的最终结果是,当RiderDataPosition
表中的某些内容发生更改时,我希望得到通知。
更新
当向数据库发送查询NOTIFY RiderPositionUpdate
时,我的测试应用程序收到响应。这意味着触发器出了问题
问题描述:
我在Docker容器中运行了一个PostgreSQL数据库,我使用的是最新版本。目标是每当RiderDataPosition
表中发生更改时向RiderPositionUpdate
通道发送通知。以下是我到目前为止所做的:
1.通知功能:
我创建了一个通知函数如下:
CREATE OR REPLACE FUNCTION "TrackSolutionsCore".notify_rider_position_change()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
PERFORM pg_notify('RiderPositionUpdate', json_build_object('operation', 'insert', 'record_id', NEW."TransponderId")::text);
RAISE NOTICE 'Inserted record with TransponderId %', NEW."TransponderId";
RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
PERFORM pg_notify('RiderPositionUpdate', json_build_object('operation', 'update', 'record_id', NEW."TransponderId")::text);
RAISE NOTICE 'Updated record with TransponderId %', NEW."TransponderId";
RETURN NEW;
ELSIF TG_OP = 'DELETE' THEN
PERFORM pg_notify('RiderPositionUpdate', json_build_object('operation', 'delete', 'record_id', OLD."TransponderId")::text);
RAISE NOTICE 'Deleted record with TransponderId %', OLD."TransponderId";
RETURN OLD;
END IF;
END;
$$ LANGUAGE plpgsql;
1.触发器:
我已经为RiderDataPosition
表上的AFTER INSERT
、AFTER UPDATE
和AFTER DELETE
操作创建了触发器。下面是其中一个触发器的例子:
CREATE TRIGGER rider_data_position_insert_trigger
AFTER INSERT ON "TrackSolutionsCore"."RiderDataPosition"
FOR EACH ROW
EXECUTE FUNCTION "TrackSolutionsCore".notify_rider_position_change();
1.表格结构:RiderDataPosition
表具有以下结构:
CREATE TABLE "RiderDataPosition"
(
"TransponderId" integer generated by default as identity
constraint "PK_RiderDataPosition"
primary key,
-- Other columns...
);
面临的问题:
尽管设置了这些触发器和通知功能,但当我对RiderDataPosition
表执行CRUD操作时,我在RiderPositionUpdate
通道上没有收到任何通知。我尝试过使用NotificationEventHandler
通过C#应用程序接收这些通知,也尝试过通过在控制台中执行LISTEN "RiderPositionUpdate"
直接通过DataGrip接收这些通知,但这两种方法都没有结果。
环境:
- PostgreSQL版本:[16个]
- Docker引擎:[v24.0.6]
测试申请
using Npgsql;
var conn = new NpgsqlConnection("connectionString");
conn.Open();
conn.Notification += (o, e) => Console.WriteLine("Received notification");
using (var cmd = new NpgsqlCommand("LISTEN RiderPositionUpdate", conn)) {
cmd.ExecuteNonQuery();
}
while (true) {
conn.Wait(); // Thread will block here
}
在DataGrip中插入新记录后的输出
问题:
1.是什么原因导致了这个问题,我如何进一步解决这个问题?
1.是否有任何特定的PostgreSQL配置或Docker设置我应该检查,以确保通知工作正常?
1.有没有一种方法可以验证触发器和函数是否正在发送通知,可能是通过PostgreSQL日志或其他方法?
1.在设置PostgreSQL触发器和通知函数时,是否有我可能忽略的常见陷阱或错误?
任何关于如何诊断和解决这个问题的见解或指导将不胜感激。谢谢你,谢谢!
1条答案
按热度按时间k10s72fa1#
你的病例不匹配。如果通道名称包含真实的大写字母,则在LISTEN命令中必须将该名称用双引号括起来。您的NOTIFY命令与您的LISTEN一起工作,因为它与LISTEN一样大小写折叠通道名称,而pg_notify没有大小写字段其第一个参数,因此它不起作用。
但更好的是,改变你的频道名称,使它没有大写字母。