oracle change notification issue

匿名 (未验证) 提交于 2019-12-03 08:54:24

问题:

I have oracle database 11.2, and I am trying to get oracle change notification working. But it does not seem to notify me, I am using ojdbc6.jar. Table is getting registered into notification; which is verified by running

select * from USER_CHANGE_NOTIFICATION_REGS 

When I execute an update on table from external client, my listener is not getting called. But when I shutdown/start database it does notify.

import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; 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 DBChangeNotification {   static final String USERNAME= "scott";   static final String PASSWORD= "tiger";   static String URL;    public static void main(String[] argv)   {     if(argv.length < 1)     {       System.out.println("Error: You need to provide the URL in the first argument.");       System.out.println("  For example: > java -classpath .:ojdbc5.jar DBChangeNotification \"jdbc:oracle:thin: @(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=yourhost.yourdomain.com)(PORT=1521)) CONNECT_DATA=(SERVICE_NAME=yourservicename)))\"");        System.exit(1);     }     URL = argv[0];     DBChangeNotification demo = new DBChangeNotification();     try     {       demo.run();     }     catch(SQLException mainSQLException )     {       mainSQLException.printStackTrace();     }   }    void run() throws SQLException   {     OracleConnection conn = connect();      // first step: create a registration on the server:     Properties prop = new Properties();      // if connected through the VPN, you need to provide the TCP address of the client.     // For example:     // prop.setProperty(OracleConnection.NTF_LOCAL_HOST,"14.14.13.12");      // Ask the server to send the ROWIDs as part of the DCN events (small performance     // cost):     prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS,"true");     //      //Set the DCN_QUERY_CHANGE_NOTIFICATION option for query registration with finer granularity.     prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION,"true");      // The following operation does a roundtrip to the database to create a new     // registration for DCN. It sends the client address (ip address and port) that     // the server will use to connect to the client and send the notification     // when necessary. Note that for now the registration is empty (we haven't registered     // any table). This also opens a new thread in the drivers. This thread will be     // dedicated to DCN (accept connection to the server and dispatch the events to      // the listeners).     DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(prop);      try     {       // add the listenerr:       DCNDemoListener list = new DCNDemoListener(this);       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 rowid from dept where 1 = 2");       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.close();       }       catch(Exception innerex){ innerex.printStackTrace(); }     }      synchronized( this )      {        // wait until we get the event       try{ this.wait();} catch( InterruptedException ie ) {}     }      // At the end: close the registration (comment out these 3 lines in order     // to leave the registration open).     OracleConnection conn3 = connect();     conn3.unregisterDatabaseChangeNotification(dcr);     conn3.close();   }    /**    * Creates a connection the database.    */   OracleConnection connect() throws SQLException   {     OracleDriver dr = new OracleDriver();     Properties prop = new Properties();     prop.setProperty("user",DBChangeNotification.USERNAME);     prop.setProperty("password",DBChangeNotification.PASSWORD);     return (OracleConnection)dr.connect(DBChangeNotification.URL,prop);   } } /**  * DCN listener: it prints out the event details in stdout.  */ class DCNDemoListener implements DatabaseChangeListener {   DBChangeNotification demo;   DCNDemoListener(DBChangeNotification dem)   {     demo = dem;   }   public void onDatabaseChangeNotification(DatabaseChangeEvent e)   {     Thread t = Thread.currentThread();     System.out.println("DCNDemoListener: got an event ("+this+" running on thread "+t+")");     System.out.println(e.toString());     synchronized( demo ){ demo.notify();}   } } 

回答1:

Well, this change notification simply doesn't work. I am going with another route Oracle Advance Queue JMS messaging instead

oracle.jms.AQjmsSession oracle.jms.AQjmsFactory 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!