简体   繁体   English

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

[英]Oracle Data Change Notification Timeout and Workflow

Good time! 美好时光!

We have the Oracle DCN feature configured in our java application. 我们在Java应用程序中配置了Oracle DCN功能。 Everything works fine, but there are some troubles on the application's shutdown. 一切正常,但关闭应用程序时会遇到一些麻烦。 If the application is down unexpectedly (for example a tomcat process is killed via the kill -9 command), DCN subscribers are left hanged in a DB ( select * from user_change_notification_regs; ). 如果应用程序意外关闭(例如,通过kill -9命令kill -9了tomcat进程),则DCN订户将被挂在DB中( select * from user_change_notification_regs; )。 Also, I can see that every subscriber has a 4294967295-second timeout. 另外,我可以看到每个订户都有4294967295-second超时。

So could somebody, please, suggest: 所以有人可以建议:

1. how to set the timeout for a subscriber; 1.如何为用户设置超时时间;
2. why subscribers are left hanged even after all JDBC connections are down. 2.为什么即使所有JDBC连接都断开后订阅者仍被挂起。 Well, if there is no correspondence between a JDBC connection and a DCN subscription, how oracle would send DCN to a java application when the last one would eventually be up (are there any ping operations from Oracle to an application, or it is something like a durable subscription in JMS)? 好吧,如果JDBC连接和DCN订阅之间没有对应关系,那么当最后一个最终启动时,oracle如何将DCN发送到java应用程序(从Oracle对应用程序执行任何ping操作,或者类似JMS中的持久订阅)?

UPDATE : I've found an answer for the first point. 更新 :我已经找到了第一点的答案。 There is the OracleConnection.NTF_TIMEOUT parameter that could be set for a DatabaseChangeRegistration : 可以为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);

The records you have persisted in user_change_notification_regs table has to be deleted explicitly since DBMS does not keep track of that 'The JDBC connection which prepared this connection is still alive' which requires a heart beat mechanism. 由于DBMS无法跟踪需要心跳机制的“准备该连接的JDBC连接仍然有效” ,因此必须明确删除user_change_notification_regs表中保留的记录。 Therefore when your server restarts, you have to explicitly delete(unregister) those records. 因此,当服务器重新启动时,您必须显式删除(注销)这些记录。 Here is an example. 这是一个例子。

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);
        } 

You can simply put this code in a static block of a class or a initializing method which will be executed only once. 您可以简单地将此代码放在将只执行一次的类的静态块或初始化方法中。 If you set a timeout for the listener, oracle server side driver enables the heart beat mechanism for your connection which could slightly decrease application performance. 如果为侦听器设置超时,则oracle服务器端驱动程序会为您的连接启用心跳机制,这可能会稍微降低应用程序性能。

Oracle will eventually clean up the dead registrations. Oracle最终将清理无效的注册。 You can also enable keep alive in the sqlnet parameter file on the server-side to speed up this cleaning process. 您还可以在服务器端的sqlnet参数文件中启用保持活动状态,以加快此清理过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM