提问人:Rajesh Ingole 提问时间:5/8/2023 最后编辑:Rajesh Ingole 更新时间:5/8/2023 访问量:226
数据库更改通知在 Java 中不起作用
Database Change Notification Not Working in Java
问:
我正在尝试获取数据库更改通知。我目前正在使用 JDK 11、ojdbc10 jar 和 Oracle 19c 企业版。
以下是我遵循的步骤:
grant change notification to <user>;
CREATE TABLE myuser.Test (TEST VARCHAR2(255));
GRANT CONNECT, CREATE TABLE, CREATE PROCEDURE, CREATE SEQUENCE TO myuser.test;GRANT CHANGE NOTIFICATION TO myuser.test;GRANT EXECUTE ON DBMS_CHANGE_NOTIFICATION TO myuser.test;Below is the Java Code
import java.sql.*;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
import oracle.jdbc.OracleStatement;
import oracle.jdbc.dcn.DatabaseChangeEvent;
import oracle.jdbc.dcn.DatabaseChangeListener;
import oracle.jdbc.dcn.DatabaseChangeRegistration;
public class Main {
public static void main(String[] args) {
try {
// Connect to the database
Class.forName("oracle.jdbc.driver.OracleDriver");
//jdbc:oracle:thin:@//HOSTNAME:PORT/SERVICENAME
OracleConnection conn = (OracleConnection) DriverManager.getConnection("jdbc:oracle:thin:@//<serverIP>:1521/orcl7", "username", "password");
Properties prop = new Properties();
prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS,"true");
prop.setProperty(OracleConnection.DCN_BEST_EFFORT,"true");
prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION,"true");
DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(prop);
try {
// add the listenerr:
DCNDemoListener list = new DCNDemoListener();
dcr.addListener(list);
// second step: add objects in the registration:
Statement stmt = conn.createStatement();
// associate the statement with the registration:
((OracleStatement) stmt).setDatabaseChangeRegistration(dcr);
ResultSet rs = stmt.executeQuery("select * from myuser.test where test='TEST'");
while (rs.next()) {
}
String[] tableNames = dcr.getTables();
for (int i = 0; i < tableNames.length; i++)
System.out.println(tableNames[i] + " is part of the registration.");
rs.close();
stmt.close();
} catch (SQLException ex) {
// if an exception occurs, we need to close the registration in order
// to interrupt the thread otherwise it will be hanging around.
if (conn != null)
conn.unregisterDatabaseChangeNotification(dcr);
throw ex;
} finally {
try {
// Note that we close the connection!
// conn.unregisterDatabaseChangeNotification(dcr);
conn.close();
} catch (Exception innerex) {
innerex.printStackTrace();
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
class DCNDemoListener implements DatabaseChangeListener
{
public void onDatabaseChangeNotification(DatabaseChangeEvent e)
{
System.out.println("Caught");
System.out.println(e.toString());
}
}
输出为:TMCDB7。TEMP 是注册的一部分。
面临的问题:
我在这里面临的问题是,我能够在数据库中注册表以获取表中的更新通知,但我在 Java 应用程序中收到任何通知。我已经检查USER_CHANGE_NOTIFICATION_REGS在哪里能够看到注册的存在。在数据库端日志中,我可以看到遇到 ORA-12535 一段时间。但后来停止出现这个错误.还检查了数据库上是否有任何故障,但没有发现其他错误。我正在通过VPN连接到数据库。
有没有人对这个问题有任何想法可以继续前进。
解决办法试图解决问题: 1.尝试增加ORA-12535的超时时间 2.检查服务器上的 1521 端口白名单以允许连接 3.尝试使用IP地址代替主机名连接到数据库 4.尝试添加以下属性并检查,但没有运气
prop.setProperty(OracleConnection.DCN_BEST_EFFORT,"true");
prop.setProperty(OracleConnection.NTF_LOCAL_TCP_PORT,"3624");
prop.setProperty(OracleConnection.NTF_LOCAL_HOST,"<IP Address>");
从 Java 1.8 升级到 Java 11,从 ojdbc 6 升级到 11
将 listerner 的 queuesize 更新为 QUEUESIZE=99
答: 暂无答案
评论