【发布时间】:2016-05-03 09:36:07
【问题描述】:
我正在为 Oracle 数据库更改通知注册一个侦听器(使用 JPA 的 EclipseLink 实现、Oracle 11.2.0.3、Oracle JDBC 瘦驱动程序 11.2.0.4):
entityManager.getTransaction().begin(); // otherwise we cannot unwrap the Connection from the entityManager
Properties properties = new Properties();
DatabaseChangeRegistration databaseChangeRegistration = ((OracleConnection)entityManager.unwrap(Connection.class)).registerDatabaseChangeNotification(properties);
databaseChangeRegistration.addListener(this);
//now you need to add whatever tables you want to monitor
try (Statement stmt = entityManager.unwrap(Connection.class).createStatement()) {
//associate the statement with the registration:
((OracleStatement) stmt).setDatabaseChangeRegistration(databaseChangeRegistration); //look up the documentation to this method [http://docs.oracle.com/cd/E11882_01/appdev.112/e13995/oracle/jdbc/OracleStatement.html#setDatabaseChangeRegistration_oracle_jdbc_dcn_DatabaseChangeRegistration_]
try (ResultSet rs = stmt.executeQuery("SELECT * FROM MY_MONITORED_TABLE WHERE ROWNUM=1")) { //you have to execute the query to link it to the statement for it to be monitored
while (rs.next()) {
//..do sth with the results if interested...
}
}
}
entityManager.getTransaction().commit();
我收到了通知,但所有通知都是每 15 分钟一次。 15 分钟是基于绝对时间,不管我什么时候开始听。发送通知的作业似乎只在服务器上以 15 分钟的固定间隔运行。
如果我直接在服务器上注册一个 PL/SQL 过程来接收通知,则通知是即时的。
我有什么选择来减少间隔?我的目标是瞬间或每隔几秒。
【问题讨论】:
-
您在事务中执行此操作,是否是事务隔离阻止您在事务超时之前看到更改?您是否看过 EclipseLink 的 DCN 支持以及它如何添加侦听器:wiki.eclipse.org/EclipseLink/UserGuide/JPA/… 您最好使用 OracleChangeNotificationListener 子类在注册调用期间执行您想要的操作。
-
@Chris 如果不在使用普通 JDBC 的事务中发送,也会出现同样的问题。据我所知,EclipseLink 的 DCN 支持只针对缓存失效,不过我去看看。
标签: java oracle jdbc oracle11g eclipselink