美好时光!
我们在 Java 应用程序中配置了 Oracle DCN 功能。一切工作正常,但应用程序关闭时出现一些问题。如果应用程序意外关闭(例如,tomcat 进程通过kill -9
命令),DCN 订阅者被挂在数据库中(select * from user_change_notification_regs;
)。另外,我可以看到每个订阅者都有一个4294967295-second
暂停。
那么有人可以建议:
1.如何为订阅者设置超时;
2.为什么即使所有 JDBC 连接都已关闭,订阅者仍处于挂起状态。好吧,如果 JDBC 连接和 DCN 订阅之间没有对应关系,那么当最后一个连接最终启动时,Oracle 如何将 DCN 发送到 Java 应用程序(是否有从 Oracle 到应用程序的任何 ping 操作,或者类似于JMS 中的持久订阅)?
UPDATE:
我找到了答案first观点。有的是OracleConnection.NTF_TIMEOUT
可以设置的参数DatabaseChangeRegistration
:
Properties properties = new Properties();
properties.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true");
properties.setProperty(OracleConnection.DCN_BEST_EFFORT, "true");
properties.setProperty(OracleConnection.NTF_TIMEOUT, "3600");
DatabaseChangeRegistration databaseChangeRegistration = oracleConnection.registerDatabaseChangeNotification(properties);
你一直保存的记录user_change_notification_regs
必须显式删除表,因为 DBMS 不会跟踪该表'准备此连接的 JDBC 连接仍然存在'这需要心跳机制。因此,当您的服务器重新启动时,您必须显式删除(取消注册)这些记录。这是一个例子。
try (Connection conn = ConnManager.getConnection();) {
if (conn.isWrapperFor(OracleConnection.class)) {
try (OracleConnection oracleConnection = conn.unwrap(OracleConnection.class);
Statement stmt = oracleConnection.createStatement()) {
ResultSet rs = stmt.executeQuery("select regid,callback from USER_CHANGE_NOTIFICATION_REGS");
while (rs.next()) {
long regid = rs.getLong(1);
String callback = rs.getString(2);
((OracleConnection) stmt.getConnection()).unregisterDatabaseChangeNotification(regid, callback);
}
}
}
} catch (SQLException ex) {
Logger.getLogger(TableBase.class.getName()).log(Level.SEVERE, null, ex);
}
您可以简单地将此代码放入类的静态块或初始化方法中,该方法仅执行一次。如果您为侦听器设置超时,Oracle 服务器端驱动程序将为您的连接启用心跳机制,这可能会稍微降低应用程序性能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)