我需要监视 oracle 表的更改,并且我正在尝试在Database Change Notifications和之间进行选择Advanced Queuing。
我不明白数据库 JDBC 开发人员指南 和getDatabaseChangeRegistration javadoc中的某些要点
如果我使用该标志注册数据库更改注册 (DCR) NTF_QOS_RELIABLE,我希望通知在我的 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);
}
}
Run Code Online (Sandbox Code Playgroud)
SQL:
-- sysdba:
-- grant change notification to scott;
-- scott:
create table a ( a int );
insert into a values ( 1 );
commit;
Run Code Online (Sandbox Code Playgroud)
NTF_QOS_RELIABLE可用于控制服务器上使用哪种类型的队列来处理通知。请参阅此文档:
https://docs.oracle.com/cd/B28359_01/appdev.111/b28395/oci10new.htm#CHDFCCJE
关于NTF_QOS_RELIABLE:
即使在节点发生故障后,Oracle RAC 的幸存实例也可用于发送和检索连续查询通知消息,因为与此注册相关的失效会永久排队到数据库中。如果为 FALSE,则失效将被排入快速内存队列中。请注意,此选项描述的是通知的持久性,而不是注册的持久性。默认情况下,注册会自动持久。
如果您的应用程序死机,则假设在重新启动期间您将从要监视的表中获取最新数据。因此,不需要在崩溃和重新启动之间发送的通知。
请注意,重新启动时需要调用conn.registerDatabaseChangeNotification重新启动驱动程序的侦听器。