I am using PostgreSQL DB and applying it's LISTEN/NOTIFY
functionality. So my listener is at my AS (Application Server) and I have triggers configured on my DB such that when CRUD operations are performed on a table a NOTIFY
request is sent on AS.
LISTENER class in 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);
}
So as my AS is up, I have configured that at startup the listener class is called (@Startup annotation
) and it's start listening on the channel.
Now this works fine if like say for testing I edit my table in DB manually, the notification is generated and the LISTENER receives it.
However, when I programmatically send a UPDATE request on the table, the UPADTE is performed successfully but LISTENER is not receiving anything.
I feel my connection of the LISTENER goes down when I send a request (it also makes a connection to edit entities), but I am not sure. I read about permanent connections and pooled connections, but not able to decide how to pursue that.
I am using pgjdbc (http://impossibl.github.io/pgjdbc-ng/) jar for async notifications as jdbc connection requires polling.
EDIT:
When I try the above listener with polling by using the standard jdbc jar (not pgjdbc), I get the notifications.
I do
PGNotification notif[] = con.getNotifications()
and I get notifications, however doing it asynchronously like below I don't get notifications.
pgConnection.addNotificationListener(new PGNotificationListener() {
@Override
public void notification(int processId, String channelName, String payload){
System.out.println("*********INSIDE NOTIFICATION*************");
}
SOLVED:
My listener was going out of scope after the function execution was completed as my listener had the function scope. So kept it into a member variable of my startup bean class and then it worked.
netstat
that the connections were in established state i.e the old connection was not lost.netstat --numeric-ports|grep 5432|grep my.ip
gave two connections (one old and one new) and both in ESTABLISHED state: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
– ShornickpgConnection.addNotificationListener(new PGNotificationListener() {})
goes out of session. Any comments? – Shornick