简体   繁体   English

Web 应用程序的 Java Oracle 数据库更改通知问题

[英]Java Oracle Database Change Notification issue with web application

I am using following code for registering and listening to Oracle database change notifications.我正在使用以下代码来注册和监听 Oracle 数据库更改通知。 This code is working fine when i run it as a standalone java program.当我将它作为独立的 Java 程序运行时,此代码运行良好。 It is receiving the notification from the database and printing as expected.它正在接收来自数据库的通知并按预期打印。

  public class DBChangeNotification {
         
    static final String USERNAME = "XXX";
    static final String PASSWORD = "YYY";
    static String URL = "jdbc:oracle:thin:@xxxx:xxxx:xxxx";

    public static void main(String[] args) {
        DBChangeNotification demo = new DBChangeNotification();
        try {
            demo.run();
        } catch (SQLException mainSQLException) {
            mainSQLException.printStackTrace();
        }
    }
    
    public void run() throws SQLException {
        OracleConnection conn = connect();
        Properties prop = new Properties();
        prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true");
        prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION, "true");
        prop.setProperty(OracleConnection.DCN_BEST_EFFORT, "true");

        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 * from xxxxxxxx where yyyy='zzzzz'");
            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);
            }
            ex.printStackTrace();
            throw ex;
        } finally {
            try {
                // Note that we close the connection!
                conn.close();
            } catch (Exception innerex) {
                innerex.printStackTrace();
            }
        }
    }
    /**
     * 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) {
        System.out.println("DCNDemoListener");
        demo = dem;
    }
    @Override
    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();
        }
    }
}

My requirement is to use this feature in a web application.我的要求是在 Web 应用程序中使用此功能。 Web application when started in the server, has to listen to data change notifications (may be on a separate thread) and notify the application through a websocket client. Web 应用程序在服务器中启动时,必须侦听数据更改通知(可能在单独的线程上)并通过 websocket 客户端通知应用程序。 I have added the following code in contextInitialized method of servlet context listener, so that it will start as soon as the application starts.我在 servlet 上下文侦听器的 contextInitialized 方法中添加了以下代码,以便它在应用程序启动时立即启动。

public class MyServletContextListener implements ServletContextListener {
 DBChangeNotification demo;
 
  @Override
  public void contextDestroyed(ServletContextEvent arg0) {
    //Notification that the servlet context is about to be shut down. 
  }

  @Override
  public void contextInitialized(ServletContextEvent arg0) {
      demo = new DBChangeNotification();
        try {
            demo.run();
        } catch (SQLException mainSQLException) {
            mainSQLException.printStackTrace();
        }
  }
}

I did not see any notifications received by the web application when database change event occurs in the registered table.当注册表中发生数据库更改事件时,我没有看到 Web 应用程序收到任何通知。 Please help me in resolving the issue.请帮助我解决问题。 I do not know whether this is a correct approach or not.... may please suggest any alternative except continuous polling.我不知道这是否是一种正确的方法......除了连续轮询之外,请提出任何替代方案。 I need to start something in the server as soon as i receive notification from database.一旦我收到来自数据库的通知,我就需要在服务器中启动一些东西。 Thank you.谢谢你。

It might be that you're running your code on an Oracle instance that doesn't have the Notification API available.可能是您在没有可用通知 API 的 Oracle 实例上运行您的代码。 Check this SO for more info 检查此 SO 以获取更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM