- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 PostgreSQL 数据库并应用它的 LISTEN/NOTIFY
功能。所以我的监听器在我的 AS(应用程序服务器)上,我在我的数据库上配置了触发器,这样当在表上执行 CRUD 操作时,一个 NOTIFY
请求会在 AS 上发送。
LISTENER 类:
@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);
}
因此,当我的 AS 启动时,我配置了在启动时调用监听器类(@Startup 注释
)并且它开始在 channel 上监听。
现在这工作正常,如果说测试我在数据库中手动编辑我的表,生成通知并且 LISTENER 接收它。
但是,当我以编程方式在表上发送 UPDATE 请求时,UPADTE 已成功执行,但 LISTENER 未收到任何内容。
当我发送请求时,我感觉我的 LISTENER 连接断开了(它也连接到编辑实体),但我不确定。我阅读了有关永久连接和池化连接的信息,但无法决定如何实现。
我正在使用 pgjdbc ( http://impossibl.github.io/pgjdbc-ng/ ) jar 进行异步通知,因为 jdbc 连接需要轮询。
编辑:
当我尝试使用标准 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 类的一个成员变量中,然后它就起作用了。
最佳答案
通知监听器由该库在内部维护为弱引用,这意味着您必须在外部持有硬引用,这样它们才不会被垃圾回收。查看 BasicContext 类第 642 - 655 行:
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”调用将返回 null 并且不会触发,如第 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);
在我看来,弱引用的用例很奇怪......
关于java - 听/通知 pgconnection 关闭 java?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37916489/
我正在尝试从 Heroku 上的 PHP 连接到 PostgreSQL。为了简化,我尝试了: function pg_connection_string_from_database_url() {
我想像这样使用 postgres CopyManager: CopyManager cp = ((PGConnection) dataSource.getConnection()).getCopyAP
我正在使用 PostgreSQL 数据库并应用它的 LISTEN/NOTIFY 功能。所以我的监听器在我的 AS(应用程序服务器)上,我在我的数据库上配置了触发器,这样当在表上执行 CRUD 操作时,
我想使用 Tomcat 在 PostgreSQL 中上传文件: @Resource(name = "jdbc/DefaultDB") private DataSource ds; Connection
异常 启动 spring-boot 应用程序时我收到了: 引起:java.sql.SQLFeatureNotSupportedException:方法 org.postgresql.jdbc.PgCo
我遇到了 Postgres 驱动程序的问题,该驱动程序是 9.1-901.jdbc4,我的数据库服务器是 Postgres 10。我在批量更新中遇到问题,因此我尝试将驱动程序更改为版本 42.2.5。
我该如何解决这个错误: java.lang.reflect.InvocationTargetException: null at sun.reflect.NativeMethodAccesso
我想在postgresql上执行一个昂贵的查询(运行时间大约7-60秒),有时查询开始后不需要结果,所以我想取消它。我想使用 vert.x 库来做到这一点。我研究过使用 io.vertx.reacti
当我使用连接对象调用 createClob 方法时,如下所示: Clob clob = con.createClob(); 抛出以下异常: Caused by: java.sql.SQLFeature
我正在使用 Postgresql 和 spring boot 2.0.4。尝试一个接一个地执行查询时会引发以下错误。我执行了以下查询,并且计数不断增加。 SELECT COUNT(*) FROM pg
我有一个 Spring 启动应用程序。我正在使用 testcontainers 对其进行测试,以确保数据库(postgres)和存储库实现执行它们应该执行的操作。 我用以下内容初始化容器并且工作得很好
我已经为 Spring Batch 创建了一个小型的 hello world 项目: 构建.gradle: buildscript { repositories { maven
当我尝试一项一项地运行测试时遇到问题。数据库连接已关闭。 根据文档 ( Containers declared as static fields ... ),我试图确保我的容器在所有测试中都被提升一次
我是一名优秀的程序员,十分优秀!