我正在使用 PostgreSQL DB 并应用它的LISTEN/NOTIFY
功能。所以我的侦听器在我的 AS(应用程序服务器)上,并且我在我的数据库上配置了触发器,这样当对表执行 CRUD 操作时,NOTIFY
就会在 AS 上发送请求。
java中的监听器类:
@Singleton
@Startup
NotificationListenerInterface.class)
public class NotificationListener extends Thread implements NotificationListenerInterface {
@Resource(mappedName="java:/RESOURCES")
private DataSource ds;
@PersistenceContext(unitName = "one")
EntityManager em;
Logger logger = Logger.getLogger(NotificationListener.class);
private Connection Conn;
private PGConnection pgConnection = null;
private NotifyRequest notifyRequest = null;
@PostConstruct
public void notificationListener() throws Throwable {
System.out.println("Notification****************");
try
{
Class.forName("com.impossibl.postgres.jdbc.PGDriver");
String url = "jdbc:pgsql://192.xx.xx.126:5432/postgres";
Conn = DriverManager.getConnection(url,"postgres","password");
this.pgConnection = (PGConnection) Conn;
System.out.println("PG CONNECTON: "+ pgConnection);
Statement listenStatement = Conn.createStatement();
listenStatement.execute("LISTEN notify_channel");
listenStatement.close();
pgConnection.addNotificationListener(new PGNotificationListener() {
@Override
public void notification(int processId, String channelName, String payload){
System.out.println("*********INSIDE NOTIFICATION*************");
System.out.println("Payload: " + jsonPayload);
}
因此,当我的 AS 启动时,我已配置在启动时调用侦听器类 ( @Startup annotation
) 并开始在频道上侦听。
现在,如果像测试我手动编辑数据库中的表,生成通知并且 LISTENER 接收它,那么这工作正常。
但是,当我以编程方式在表上发送 UPDATE 请求时,UPADTE 已成功执行,但 LISTENER 没有收到任何内容。
当我发送请求时,我感觉与 LISTENER 的连接断开了(它还与编辑实体建立了连接),但我不确定。我阅读了有关永久连接和池连接的信息,但无法决定如何进行。
我正在使用 pgjdbc ( http://impossibl.github.io/pgjdbc-ng/ ) jar 进行异步通知,因为 jdbc 连接需要轮询。
编辑:
当我使用标准 jdbc jar(而不是 pgjdbc)尝试使用上述侦听器进行轮询时,我会收到通知。
我这样做
PGNotification notif[] = con.getNotifications()
了,我收到了通知,但是像下面这样异步执行,我没有收到通知。
pgConnection.addNotificationListener(new PGNotificationListener() {
@Override
public void notification(int processId, String channelName, String payload){
System.out.println("*********INSIDE NOTIFICATION*************");
}
解决了:
函数执行完成后,我的侦听器超出了范围,因为我的侦听器具有函数范围。所以将它保存到我的启动 bean 类的成员变量中,然后它就可以工作了。