8

Ben PostgreSQL DB kullanarak ve uygulayarak bu LISTEN/NOTIFY işlevselliğini duyuyorum. Bu yüzden dinleyicim AS'mda (Uygulama Sunucusu) ve DB'imde yapılandırılmış tetikleyiciler var. Böylece CRUD işlemleri bir tabloda gerçekleştirildiğinde AS üzerinde NOTIFY isteği gönderiliyor.LISTEN/NOTIFY pgconnection java gider?

DİNLEYİCİ java sınıfı: Benim AS yukarı olduğu gibi

 @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); 

} 

Yani, başlangıçta dinleyici sınıfı ( @Startup annotation) olduğunu söyledi yapılandırmış ve kanalda dinlemeye başlamak var.

Şimdi böyle manuel DB benim tabloyu düzenlemek test için diyorsan, gayet iyi çalışıyor bildirimi oluşturulur ve DİNLEYİCİ bunu alır. Ben programlı masada bir UPDATE isteği gönderdiğinizde

Ancak, UPADTE başarıyla gerçekleştirilir ama DİNLEYİCİ şey almıyor.

Ben bir istek (aynı zamanda varlıkları düzenlemek için bir bağlantı yapar) gönderirken dinleyici benim bağlantı iner hissetmek, ama emin değilim. Kalıcı bağlantılar ve birleştirilmiş bağlantılar hakkında okudum, ancak bunu nasıl sürdüreceğine karar veremiyorum. jdbc bağlantı yoklama gereğine göre

ben zaman uyumsuz bildirimleri için pgjdbc (http://impossibl.github.io/pgjdbc-ng/) kavanoz kullanıyorum.

DÜZENLEME:

Ben standart jdbc kavanoz kullanarak yoklama ile yukarıdaki dinleyici çalıştığınızda (pgjdbc değil), ben bildirimler alabilirsiniz.

PGNotification notif[] = con.getNotifications() ve bildirimleri alıyorum, ancak aşağıdaki gibi zaman uyumsuz olarak yapıyorum.

pgConnection.addNotificationListener(new PGNotificationListener() { 

     @Override 
     public void notification(int processId, String channelName, String payload){ 

      System.out.println("*********INSIDE NOTIFICATION*************"); 
     } 

ÇÖZÜLDÜ: benim dinleyici işlevi kapsamını vardı fonksiyon icra tamamlandıktan sonra My dinleyici kapsam dışına gidiyordu

. Bu yüzden başlangıç ​​fasulyesi sınıfımın bir üye değişkeni olarak tuttu ve sonra işe yaradı.

+0

Dinleyicinizin içinde 'jsonPayload' değişkeni mevcut değil. Ayrıca, güncellemelerinizi yazmak için aynı bağlantıyı kullanıyor musunuz?Eklenen dinleyici ile bağlantınızın kapsam dışı kaldığı ve GC tarafından yok olduğu mümkün. –

+0

Aynı bağlantıyı kullanmıyorum. Ancak 'netstat' kullanarak bağlantıların kurulmuş durumda olduğunu kontrol ettim, yani eski bağlantı kaybolmadı. netstat --numeric-ports | grep 5432 | grep my.ip' iki bağlantı (bir eski ve bir yeni) verdi ve her ikisi de ESTABLISHED durumunda: tcp 0 0 192.168.5.126:5432 192.168.105.213:46802 KURULU tcp 0 0 192.168.5.126:5432 192.168.105.213:46805 KURULUM ' –

+0

@ LukeA.Leber: Lütfen soruyu düzenlemeyi kontrol edin. –

cevap

5

bildirim dinleyici içten o kütüphanede tarafından muhafaza edilir onlar çöp toplanacak etmeyecek şekilde dışarıdan sert bir başvuru tutmak zorunda anlamına zayıf referanslar. - 710

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, dinleyicinizin alır boş dönecektir zayıf referansa "get" çağrıları ve hatlarından 690 görüldüğü gibi ateş etmezse: 655 - BasicContext sınıf hatlarını 642 göz atın Bunu düzeltmek için

@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); 
     } 

    } 

} 

gibi bildirim dinleyicileri ekleyin:

/// 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); 

Oldukça garip bir kullanım senaryosunu zayıf referanslar için bence ...

+0

Teşekkürler, günümü kurtardın. Bu konuda çok kafam karışmıştı – sanket1729