如何使用Postgres数据库在Java中获得异步/事件驱动的LISTEN / NOTIFY支持?

据我所知,Java中LISTEN / NOTIFY的JDBC驱动程序不支持真正的事件驱动通知。 您必须经常轮询数据库以查看是否有新通知。

我有什么选择在Java(可能是JDBC以外的东西?)中,如果有的话,以真正的事件驱动方式异步获取通知而不进行轮询?

使用pgjdbc-ng驱动程序。

http://impossibl.github.io/pgjdbc-ng/

它支持异步通知,无需轮询。 我成功地使用了它。

请参阅http://blog.databasepatterns.com/2014/04/postgresql-nofify-websocket-spring-mvc.html

Oleg也有一个很好的例子

这是使用com.impossibl.postgres.api( pgjdbc-ng-0.6-complete.jar )和JDK 1.8的异步模式:

import com.impossibl.postgres.api.jdbc.PGConnection; import com.impossibl.postgres.api.jdbc.PGNotificationListener; import com.impossibl.postgres.jdbc.PGDataSource; import java.sql.Statement; public static void listenToNotifyMessage(){ PGDataSource dataSource = new PGDataSource(); dataSource.setHost("localhost"); dataSource.setPort(5432); dataSource.setDatabase("database_name"); dataSource.setUser("postgres"); dataSource.setPassword("password"); PGNotificationListener listener = (int processId, String channelName, String payload) -> System.out.println("notification = " + payload); try (PGConnection connection = (PGConnection) dataSource.getConnection()){ Statement statement = connection.createStatement(); statement.execute("LISTEN test"); statement.close(); connection.addNotificationListener(listener); while (true){ } } catch (Exception e) { System.err.println(e); } } 

为您的数据库创建一个触发器函数:

 CREATE OR REPLACE FUNCTION notify_change() RETURNS TRIGGER AS $$ BEGIN SELECT pg_notify('test', TG_TABLE_NAME); RETURN NEW; END; $$ LANGUAGE plpgsql; 

为要跟踪的每个表分配触发器:

 CREATE TRIGGER table_change AFTER INSERT OR UPDATE OR DELETE ON table_name FOR EACH ROW EXECUTE PROCEDURE notify_change(); 

似乎没有办法解决这个问题。 您可以解决这个问题,因为已经提出了几条建议,但最终,您将进行民意调查。

如果您可以轮询数据库,请按以下步骤操作:

 PGConnection con = ... try (Statement s = con.createStatement()) { s.executeUpdate("listen x"); s.executeUpdate("notify x, 'abc'"); } for (PGNotification n : con.getNotifications()) { System.out.println(String.format("%s, %s, %s", n.getPID(), n.getName(), n.getParameter())); } 

以上将产生类似于:

 11796, x, abc 11796, x, xyz 

您必须至少运行一个语句才能从连接中获取新通知。