我想让我的PostgreSQL服务器在一段数据发生变化时发出通知,最好是通过JMS,还要考虑任何其他Pub-Sub机制或回调。
如果有可能,有什么想法吗?
是否有可用的Java附加软件包复制此类功能?
答案 0 :(得分:8)
编辑:我被告知PostgreSQL 支持Java中的存储过程。这意味着以下方法变得可行:
基本上,我要采用的方法是在你想要观看的任何内容上设置一个触发器,然后从中调用存储过程。然后,存储过程需要与DB服务器外部的世界通信;我曾经在Java中使用这样的SP来打开与同一服务器上的进程的套接字连接,并监听端口。如果最糟糕的情况发生了,你可以编写一个文件,然后像imon一样监视该文件,或者你可以在自己的exec()shell中启动一个程序......就像那样。
答案 1 :(得分:3)
最简单的方法是使用LISTEN / NOTIFY接口,编写自己的程序连接到数据库,发出一些LISTEN,并在收到通知时做任何你想要的事情 - 例如感知信息JMS,或简单地完成应该做的事情,而不添加额外的传输层。
答案 2 :(得分:3)
您当然可以创建一个Java语言存储过程并将其放入PostgreSQL中。但是为什么不保持简单和可调试,直到你知道你的消息传递方案完美运行为止?如果我这样做(我实际上在做类似的事情)这就是我要做的事情。
(1)创建一个“出站消息”表,其中包含有效负载的列和JMS消息的其他信息。我在每一行都加了一个时间戳列。
(2)为要生成消息的每个项目编写数据库触发器。让触发器在您的“出站消息”表中插入一行。
(3)单元测试(1)和(2)通过在数据库中更改应生成消息的内容时查看出站消息表的内容。
(4)给自己写一个简单但高性能的Java JDBC客户端程序,它将查询这个出站消息表,为每一行发送一条JMS消息,然后删除它。按时间戳排序查询中的行以保留您的消息顺序。为了使其具有高性能,您需要在PreparedStatement对象和堆管理的其他方面做得很好。
(5)通过运行它几次进行单元测试(4),同时对数据库进行消息生成更改。
(6)设置此程序,每分钟重复操作(6)几次,同时使用单个持久JDBC连接。对小表或空表的查询不是很昂贵,所以这不会打乱你的表服务器。
(7)系统测试整个设置。
(8)弄清楚如何从crontab或启动脚本启动Java程序。
当您完成所有这些工作后,您将拥有一个正常运行的消息/通知系统,可用于系统集成。更重要的是,您将确切地知道您希望Java消息源软件做什么。一旦启动并运行,如果消息的延迟或数据库开销被证明是一个大问题,那么您可以将Java程序迁移到存储过程中。
另请注意,PERL和Apache ActiveMQ包中内置的其他语言都有消息发起绑定,因此您可以选择如何实现消息发起代理。
这种方法恰好有两个优点:你并不严格依赖于postgreSQL独特的存储过程方案,而且你不会将具有外部通信依赖性的代码放入你的表服务器。
祝你好运。答案 3 :(得分:2)
我会将PL/Java安装到Postgres并为您感兴趣的数据编写基于存储过程的触发器,然后在调用时调用JMS。 PL / Java文档很好地涵盖了触发器+存储过程部分。
我没有使用触发器代码中的JMS,但我很确定没有理由说它不可行,因为这是标准的Java代码,我对文档的快速检查也没有' t表示任何可疑的事情。
另一种可能性是使用perl,python或任何其他可用于postgres存储过程开发的语言通过代理服务调用JMS。就像JMS没有标准的有线协议一样,你必须编写一个代理服务来进行翻译。
答案 4 :(得分:0)
如果无法通过JDBC访问LISTEN / NOTIFY,也许您可以通过LOCK语句或简单的“SELECT ... FOR UPDATE”和“SELECT”实现长轮询HTTP类似Comet的机制。 .. FOR SHARE“或来自导致其他交易阻止的交易中的其他类似查询。
消息撰写方可以例如启动一个事务,执行“SELECT ... FOR UPDATE”,等待(java代码)直到某个东西发生变化,或者一个计时器到期(比如30秒左右),更新锁定行以指示数据(其他地方?)是可用并提交事务以取消阻止其他人。然后立即用“SELECT ... FOR UPDATE”重复一个新事务。
消息阅读方将执行“SELECT ... FOR SHARE”,当其他地方启动的“SELECT ... FOR UPDATE”处于活动状态时,它将被阻止。当消息编写方的交易结束时,它会返回消息可用性或消息数据本身的指示。
希望PostgreSQL能够公平地对各方进行排队,这样就不会有活锁持续阻塞消息阅读方的风险。