Database Change Notification

来源:互联网 发布:淘宝助手下载 编辑:程序博客网 时间:2024/05/21 00:51

Database Change Notification的作用就是当数据库中的被监听table变化时(包括数据和表结构的更改),自动向应用程序发出一个通知。这对读多写少应用的缓存更新,以及避免轮询数据库很有用。

需要3个步骤:
1. 注册。

2. 用一个查询表示监听哪个(些)表的修改通知。

3. 响应。

原理是程序另起了一个线程 并向数据库注册了一个IP和端口,当数据库数据发生改变时通知程序。



官方说支持11G,其实10.2也可以跑

运行环境:linux jdk6

jar :ojdbc6.jar


代码:

import java.lang.reflect.Field;import java.net.InetAddress;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.Properties;import oracle.jdbc.OracleStatement;import oracle.jdbc.dcn.DatabaseChangeEvent;import oracle.jdbc.dcn.DatabaseChangeListener;import oracle.jdbc.dcn.DatabaseChangeRegistration;import oracle.jdbc.driver.OracleConnection;import oracle.jdbc.pool.OracleDataSource;public class Test { public static void main(String[] a) {   try {     OracleDataSource dataSource = new OracleDataSource();     dataSource.setUser("***");     dataSource.setPassword("***");     dataSource.setURL("jdbc:oracle:thin:@192.168.***.***:1521:***");     final OracleConnection conn = (OracleConnection) dataSource.getConnection();     Properties prop = new Properties();     prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true"); // 要取得更改记录的rowid     // prop.setProperty(OracleConnection.DCN_IGNORE_DELETEOP, "true");     // // 忽略delete     prop.setProperty(OracleConnection.NTF_TIMEOUT, "3600"); // 设置超时,这里是1个小时,届时数据库和驱动器的资源将自动释放。如果为0或不设置,则永不过期,直到程序停止监听,当数据库发送更新通知时,因没有监听端口,数据库随后释放资源。     DatabaseChangeRegistration databaseChangeRegistration = conn.registerDatabaseChangeNotification(prop);     OracleStatement statement = (OracleStatement) conn.createStatement();     statement.setDatabaseChangeRegistration(databaseChangeRegistration);     databaseChangeRegistration.addListener(new DatabaseChangeListener() { // 增加事件监听         public void onDatabaseChangeNotification(DatabaseChangeEvent databaseChangeEvent) {           System.out.println("DCNListener: got an event (" + this + ")");         }       });     // add objects:     statement.executeQuery("select * from t_12580_shop");     statement.close();     conn.close();     System.out.println("Registered database change notification for table:t_12580_shop");   }   catch (Exception e) {     System.out.print(e.getLocalizedMessage());   } }}


 


当你注册一个SELECT查询,你注册的是所涉及的表的名称,而不是查询本身。换句话说,你可能会选择一个表中的单一行,如果另一行被更新时,系统会通知您,虽然您的查询的结果并没有改变。

在放到线上环境时出现了程序监听不到数据改变的问题,查看源码后发现向数据库注册的IP是127.0.0.1

源码中获取本机IP的代码是InetAddress.getLocalHost().getHostAddress()

需要在/etc/hoses中配置hoseName 和内网IP的 映射,配置过后成功运行

原创粉丝点击