3

我想让我的 PostgreSQL 服务器在数据发生更改时发送通知,最好是通过 JMS,但还要考虑任何其他 Pub-Sub 机制或回调。

如果可能的话,有什么想法吗?

是否有任何可用的 Java 附加包可以复制这种功能?

4

5 回答 5

8

编辑:我被告知 PostgreSQL确实支持 Java 中的存储过程。这意味着以下方法变得可行:

本质上,我会采用的方法是在您想要观看的任何内容上放置一个触发器,然后从中调用一个存储过程。然后存储过程需要与数据库服务器外部的世界进行通信;我曾经在 Java 中做过这样的 SP,它打开了一个套接字连接到同一服务器上侦听端口的进程。如果最坏的情况发生了,您可能会编写一个文件并让 imon 监控该文件,或者您可以在自己的 exec() shell 中启动一个程序......类似的东西。

于 2009-11-20T15:58:42.483 回答
4

您当然可以创建 Java 语言存储过程并将其放入 PostgreSQL。但是,在您知道自己的消息传递方案完美运行之前,为什么不让它保持简单和可调试呢?如果我这样做(我实际上正在做类似的事情),这就是我要做的。

(1) 创建一个“出站消息”表,其中包含有效负载列和 JMS 消息的其他信息。我会在每一行中放置一个时间戳列。

(2) 为要生成消息的每个项目编写一个数据库触发器。让触发器在“出站消息”表中插入一行。

(3) 单元测试 (1) 和 (2) 通过在您更改数据库中应该生成消息的内容时查看出站消息表的内容。

(4) 自己编写一个简单但高性能的 Java JDBC 客户端程序,它将查询这个出站消息表,为每一行发送一条 JMS 消息,然后删除它。按时间戳对查询中的行进行排序以保留消息顺序。要获得高性能,您需要做好 PreparedStatement 对象和堆管理的其他方面的工作。

(5) 单元测试 (4) 在您的数据库发生消息生成更改时运行几次。

(6) 将此程序设置为每分钟重复操作 (6) 几次,同时使用单个持久 JDBC 连接。对小表或空表的查询不是很昂贵,因此这不会破坏您的表服务器。

(7) 系统测试整个设置。

(8) 弄清楚如何从你的 crontab 或你的启动脚本启动你的 Java 程序。

当您完成所有这些工作时,您将拥有一个功能正常的消息传递/通知系统,可以进行系统集成。更重要的是,您将确切地知道您希望 Java 消息发起软件做什么。一旦你启动并运行,如果你的消息延迟或数据库开销被证明是一个大问题,那么你可以将你的 Java 程序迁移到存储过程中。

另请注意,Apache ActiveMQ 包中内置了 PERL 和其他语言的消息来源绑定,因此您可以选择如何实现消息来源代理。

这种方法恰好有两个优点:您不会严重依赖 postgreSQL 独特的存储过程方案,并且您不会将具有外部通信依赖关系的代码放入表服务器中。

祝你好运。

于 2009-11-27T23:19:20.230 回答
3

最简单的方法是使用LISTEN / NOTIFY接口,编写您自己的程序连接到数据库,发出一些 LISTEN,并在收到通知时执行您想要的任何操作 - 例如通过 JMS 感知信息,或者只是执行应该执行的操作,无需增加额外的运输层。

于 2009-11-20T16:17:08.890 回答
2

我会将PL/Java安装到 Postgres 并为您感兴趣的数据编写一个基于存储过程的触发器,然后在被调用时调用 JMS。PL/Java 文档很好地涵盖了触发器 + 存储过程部分。

我没有使用触发代码中的 JMS,但我很确定它没有理由不可行,因为这是标准 Java 代码,我对文档的快速重新检查也没有说明任何问题可疑的。

另一种可能性是通过代理服务调用 JMS,使用 perl、python 或任何其他可用于 postgres 存储过程开发的语言。就像 JMS 没有标准的有线协议一样,您必须编写一个代理服务来进行翻译。

于 2009-11-25T23:08:53.470 回答
1

如果 LISTEN/NOTIFY 无法通过 JDBC 访问,也许您可​​以通过LOCK语句或简单的“SELECT ... FOR UPDATE”和“SELECT ... FOR SHARE”或其他实现长轮询 HTTP 彗星式机制来自事务中的类似查询会导致其他事务阻塞。

消息编写方可以例如启动事务,执行“SELECT ... FOR UPDATE”,等待(java 代码)直到发生某些变化或计时器到期(例如在 30 秒左右之后),更新锁定的行以指示如果数据(其他地方?)可用并提交事务以解除阻止其他人。然后立即使用“SELECT ... FOR UPDATE”重复一个新事务。

消息阅读方将执行“SELECT ... FOR SHARE”,这将在其他地方启动的“SELECT ... FOR UPDATE”处于活动状态时阻塞。当消息编写方的事务结束时,它将返回消息可用性或消息数据本身的指示。

希望 PostgreSQL 公平地对各方进行排队,这样就不会有活锁持续阻塞消息读取方的风险。

于 2009-11-25T22:47:48.947 回答