听/通知PGCONNECTION降低了Java



我正在使用postgresql db并应用其LISTEN/NOTIFY功能。因此,我的侦听器在我的AS(应用程序服务器)上,并且我在DB上配置了触发器,因此当在表上执行CRUD操作时,请发送NOTIFY请求。

侦听器 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);
}

因此,我已经配置了在启动时调用侦听器类(@Startup annotation),并且在频道上开始侦听。

现在可以很好地工作,如果可以进行测试,我会在DB中手动编辑我的表格,并生成通知并收到它。

但是,当我在表上编程发送更新请求时,Upadte已成功执行,但听众没有收到任何内容。

我觉得当我发送请求时,听众的联系会降低(这也与编辑实体建立了连接),但我不确定。我阅读了有关永久连接和汇总连接的信息,但无法决定如何追求。

我正在使用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类的成员变量,然后起作用。

通知听众内部维护该库作为弱参考,这意味着您必须在外部持有硬参考,以免收集垃圾。查看BasicContext类行642-655:

public void addNotificationListener(String name, String channelNameFilter, NotificationListener listener) {
    name = nullToEmpty(name);
    channelNameFilter = channelNameFilter != null ? channelNameFilter : ".*";
    Pattern channelNameFilterPattern = Pattern.compile(channelNameFilter);
    NotificationKey key = new NotificationKey(name, channelNameFilterPattern);
    synchronized (notificationListeners) {
      notificationListeners.put(key, new WeakReference<NotificationListener>(listener));
    }
}

如果GC接您的听众,请打电话给" get"弱参考将返回null,并且不会从第690-710行中看到的发射。

  @Override
  public synchronized void reportNotification(int processId, String channelName, String payload) {
    Iterator<Map.Entry<NotificationKey, WeakReference<NotificationListener>>> iter = notificationListeners.entrySet().iterator();
    while (iter.hasNext()) {
      Map.Entry<NotificationKey, WeakReference<NotificationListener>> entry = iter.next();
      NotificationListener listener = entry.getValue().get();
      if (listener == null) {
        iter.remove();
      }
      else if (entry.getKey().channelNameFilter.matcher(channelName).matches()) {
        listener.notification(processId, channelName, payload);
      }
    }
}

要解决此问题,请添加您的通知听众:

/// Do not let this reference go out of scope!
    PGNotificationListener listener = new PGNotificationListener() {
    @Override
    public void notification(int processId, String channelName, String payload) {
        // interesting code
    };
};
    pgConnection.addNotificationListener(listener);

我认为弱参考的一个奇怪用例...

相关内容

  • 没有找到相关文章

最新更新