Oracle数据更改通知超时和工作流

时间:2014-05-08 13:13:26

标签: java oracle

美好时光!

我们在Java应用程序中配置了Oracle DCN功能。一切正常,但应用程序关闭有一些麻烦。如果应用程序意外关闭(例如,通过kill -9命令终止了tomcat进程),则DCN订阅者将被挂在数据库(select * from user_change_notification_regs;)中。此外,我可以看到每个订阅者都有4294967295-second超时。

有人可以,建议:

1。如何设置订阅者的超时;
  2。即使在所有JDBC连接断开后,订阅者仍被绞死。好吧,如果JDBC连接和DCN订阅之间没有对应关系,那么当最后一个应用程序最终启动时,oracle如何将DCN发送到java应用程序(是否有从Oracle到应用程序的ping操作,或者类似于在JMS中持久订阅)?

更新: 我找到了第一个点的答案。可以为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);

2 个答案:

答案 0 :(得分:0)

您必须明确删除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服务器端驱动程序会为您的连接启用心跳机制,这可能会略微降低应用程序性能。

答案 1 :(得分:0)

甲骨文最终将清理死亡的注册。您还可以在服务器端的sqlnet参数文件中启用keep alive,以加快此清理过程。