持久性数据库更改通知

时间:2017-11-03 12:25:00

标签: java oracle jdbc

我需要监控oracle表格进行更改,并尝试在Database Change NotificationsAdvanced Queuing之间进行选择。

我不理解Database JDBC Developer's Guide中的某些要点 和getDatabaseChangeRegistration javadoc

如果我使用NTF_QOS_RELIABLE标志注册数据库更改注册(DCR),我希望在我的jdbc应用程序关闭时通知仍然存在。但是,在我的应用重新启动后,我没有看到恢复现有DCR的方法:根据javadoc,getDatabaseChangeRegistration()仅适用于PLSQL侦听器。似乎jdbc DCR在我的应用程序死亡时被销毁,我甚至不必注销它们。

我的程序重启后,我有时会收到先前注册ID的通知。每次启动我的应用时都没有必要致电stmt.setDatabaseChangeRegistration()

我从未收到应用程序停机时发生的更改,这是最大的问题。 NTF_QOS_RELIABLE做了什么?

package org.foo;

import static oracle.jdbc.OracleConnection.*;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.Locale;
import java.util.Properties;

import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleStatement;
import oracle.jdbc.dcn.DatabaseChangeEvent;
import oracle.jdbc.dcn.DatabaseChangeListener;
import oracle.jdbc.dcn.DatabaseChangeRegistration;

// CHECKSTYLE.OFF: Name|Reg
public final class TestDbListener {

    private TestDbListener() {}

    public static void main(final String[] args) throws Exception {
        Locale.setDefault(Locale.US);

        Class.forName("oracle.jdbc.OracleDriver");
        final OracleConnection conn =
                (OracleConnection) DriverManager.getConnection(
                        "jdbc:oracle:thin:@192.168.56.150:1521:xe", "scott", "tiger");

        final Properties props = new Properties();
        props.setProperty(NTF_QOS_RELIABLE, "true");

        final DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(props);
        final DCNListener list = new DCNListener();
        dcr.addListener(list);

        if (true) {

            // now you need to add whatever tables you want to monitor
            final OracleStatement stmt = (OracleStatement) conn.createStatement();
            // associate the statement with the registration:
            stmt.setDatabaseChangeRegistration(dcr);

            final String sql = "select * from a where 1=2";
            final ResultSet rs = stmt.executeQuery(sql);

        }

        final String[] tableNames = dcr.getTables();
        for (int i = 0; i < tableNames.length; i++) {
            System.out.println(tableNames[i] + " has been registered.");
        }

        Thread.sleep(1000000);

        // rs.close();

    }

}

class DCNListener implements DatabaseChangeListener {

    @Override
    public void onDatabaseChangeNotification(final DatabaseChangeEvent event) {
        System.out.println("onDatabaseChangeNotification: " + event);
    }
}

SQL:

-- sysdba: 
-- grant change notification to scott;

-- scott:
create table a ( a int );

insert into a values ( 1 );
commit;

1 个答案:

答案 0 :(得分:0)

NTF_QOS_RELIABLE可用于控制服务器上使用哪种类型的队列来处理通知。看到这个文档: https://docs.oracle.com/cd/B28359_01/appdev.111/b28395/oci10new.htm#CHDFCCJE

关于NTF_QOS_RELIABLE

  

可以使用Oracle RAC的存活实例进行发送和检索   连续查询通知消息,即使在节点发生故障之后   因为与此注册相关的失效已排队   持续进入数据库。如果为FALSE,则失效   入队快速内存队列。请注意,此选项描述   通知的持久性而不是持久性   注册。默认情况下,注册会自动保留。

如果您的应用程序死亡,则假设在重新启动期间,您将从要监视的表中获取最新数据。因此,不需要在崩溃和重新启动之间发送的通知。

请注意,重新启动时,需要调用conn.registerDatabaseChangeNotification来重新启动驱动程序的侦听器。