[英]Oracle Data Change Notification Timeout and Workflow
美好时光!
我们在Java应用程序中配置了Oracle DCN功能。 一切正常,但关闭应用程序时会遇到一些麻烦。 如果应用程序意外关闭(例如,通过kill -9
命令kill -9
了tomcat进程),则DCN订户将被挂在DB中( select * from user_change_notification_regs;
)。 另外,我可以看到每个订户都有4294967295-second
超时。
所以有人可以建议:
1.如何为用户设置超时时间;
2.为什么即使所有JDBC连接都断开后订阅者仍被挂起。 好吧,如果JDBC连接和DCN订阅之间没有对应关系,那么当最后一个最终启动时,oracle如何将DCN发送到java应用程序(从Oracle对应用程序执行任何ping操作,或者类似JMS中的持久订阅)?
更新 :我已经找到了第一点的答案。 可以为DatabaseChangeRegistration
设置OracleConnection.NTF_TIMEOUT
参数:
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);
由于DBMS无法跟踪需要心跳机制的“准备该连接的JDBC连接仍然有效” ,因此必须明确删除user_change_notification_regs
表中保留的记录。 因此,当服务器重新启动时,您必须显式删除(注销)这些记录。 这是一个例子。
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服务器端驱动程序会为您的连接启用心跳机制,这可能会稍微降低应用程序性能。
Oracle最终将清理无效的注册。 您还可以在服务器端的sqlnet参数文件中启用保持活动状态,以加快此清理过程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.