PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

LISTEN/NOTIFY pgconnection прекъсва java?

Слушателите на известия се поддържат вътрешно от тази библиотека като слаби препратки, което означава, че трябва да държите твърда препратка външно, за да не бъдат събирани на боклук. Вижте редовете 642 - 655 на класа BasicContext:

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" на слабата препратка ще върнат нула и няма да се активират, както се вижда от редове 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);

Според мен доста странен случай на използване на слаби препратки...




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Travis CI:ФАТАЛНО:ролята не съществува

  2. Как да използвате една и съща стойност няколко пъти в подготвения оператор на jdbc postgresql

  3. Как да изградим нормализирана таблица от един денормализиран текстов файл?

  4. Конфигуриране на PostgreSQL за непрекъснатост на бизнеса

  5. Най-добрият начин за съхраняване на последно докоснато време в Cassandra