私はPostgreSQL DBを使用しており、その機能をLISTEN/NOTIFY
に適用しています。だから私のリスナーは私のAS(Application Server)にあり、CRUD操作がテーブル上で実行されたときにNOTIFY
要求がAS上で送信されるように、自分のDB上に設定されたトリガーを持っています。 JavaでLISTEN/NOTIFY pgconnectionがjavaになる?
LISTENERクラス:私のASがアップしているよう
@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で手動で編集すると通知が生成され、LISTENERがそれを受け取るとうまくいきます。
ただし、プログラムでテーブルのUPDATE要求を送信すると、UPADTEは正常に実行されますが、LISTENERは何も受信しません。
リクエストを送信したときにリスナーとの接続が切断されていると感じましたが(エンティティの編集にも接続します)、わかりません。永続的な接続とプールされた接続については読んだが、それを追求する方法を決めることはできなかった。
jdbc接続でポーリングが必要なため、非同期通知用にpgjdbc(http://impossibl.github.io/pgjdbc-ng/)jarを使用しています。
編集:私は、標準の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クラスのメンバ変数に入れておき、それがうまくいきました。
リスナーの内部で、変数 'jsonPayload'が存在しません。また、アップデートを書き込むために同じ接続を使用していますか?アタッチされたリスナーとの接続が有効範囲外になり、GCによって破棄される可能性があります。 –
私は同じ接続を使用していません。しかし、 'netstat'を使って接続が確立された状態にあること、すなわち古い接続が失われていないことを確認しました。 'netstat --numeric-ports | grep 5432 | grep my.ip'はESTABLISHED状態の2つの接続(古いものと新しいもの)を与えました:' 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:質問の編集を確認してください。 –