Używam PostgreSQL DB i stosowanie jego funkcji LISTEN/NOTIFY
. Tak więc mój słuchacz jest na moim AS (Application Server) i mam wyzwalacze skonfigurowane na moim DB tak, że gdy operacje CRUD są wykonywane na stole, żądanie NOTIFY
jest wysyłane na AS.LISTEN/NOTIFY pgconnection idzie w dół java?
słuchacz klasa w Javie:
@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);
}
Tak jak mój AS jest gotowy, mam skonfigurowany, że przy starcie klasa słuchacz nazywa (@Startup annotation
) i to zacząć słuchać na kanale.
Teraz działa dobrze, jeśli chcesz powiedzieć, że do testowania Edytuję moją tabelę w DB ręcznie, generowane jest powiadomienie, a LISTENER je otrzymuje.
Jednak, gdy programowo wysyłam żądanie aktualizacji na stole, UPADTE jest wykonywane pomyślnie, ale LISTENER nic nie otrzymuje.
Uważam, że moje połączenie z LISTENERÓW przestaje działać, gdy wysyłam żądanie (to także tworzy połączenie z podmiotami edycji), ale nie jestem pewien. Czytałem o stałych połączeniach i połączonych połączeniach, ale nie byłem w stanie zdecydować, jak tego dokonać.
Używam słoika pgjdbc (http://impossibl.github.io/pgjdbc-ng/) do powiadomień asynchronicznych, ponieważ połączenie jdbc wymaga sondowania.
EDIT:
Gdy próbuję powyższy słuchacza odpytywania za pomocą standardowego jdbc słoik (nie pgjdbc), otrzymuję powiadomień.
Mam i otrzymuję powiadomienia, jednak wykonuję to asynchronicznie, jak poniżej, nie otrzymuję powiadomień.
pgConnection.addNotificationListener(new PGNotificationListener() {
@Override
public void notification(int processId, String channelName, String payload){
System.out.println("*********INSIDE NOTIFICATION*************");
}
rozwiązany:
Mój słuchacz jechał z zakresu po wykonaniu funkcja została zakończona, jak mój słuchacz miał zakres funkcji. Zatrzymałem go więc w zmiennej członkowskiej mojej klasy komponentu bean, a następnie zadziałało.
Wewnątrz odbiornika zmienna "jsonPayload" nie istnieje. Czy używasz tego samego połączenia do pisania swoich aktualizacji?Możliwe jest, że twoje połączenie z dołączonym słuchaczem wykracza poza zakres i jest niszczone przez GC. –
Nie używam tego samego połączenia. Ale sprawdziłem przy użyciu 'netstat', że połączenia były w stanie ustalonym, tzn. Stare połączenie nie zostało utracone. 'netstat -numeric-ports | grep 5432 | grep my.ip' dał dwa połączenia (jeden stary i jeden nowy) i oba w stanie ESTABLISHED:' tcp 0 0 192.168.5.126:5432 192.168.105.213:46802 ESTABLISHED tcp 0 0 192.168.5.126:5432 192.168.105.213:46805 ESTABLISHED' –
@ LukeA.Leber: Sprawdź edycję na pytanie. –