kagamihogeの日記

kagamihogeの日記です。

Oracleのデータベース変更通知

JDBCドライバでは、SQL問合せをデータベースに登録して、次のイベントの発生時に通知を受け取ることができます。

問合せに関連付けられたオブジェクトに対するDMLまたはDDL変更。

結果セットに影響を与えるDMLまたはDDL変更。

Oracle Database JDBC開発者ガイド 11gリリース2(11.2)- 26 データベース変更通知 より抜粋

とまぁ、面白そうな機能があるのでとりあえず使ってみる。

環境

ソースコードなど

public class OracleNotify {

    public static void main(String[] args) throws Exception {
        Connection connection = DriverManager.getConnection(
                "jdbc:oracle:thin:@localhost:1521:XE", "xxxx", "xxxx");
        
        Properties prop = new Properties();
        prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS,"true");
        prop.setProperty(OracleConnection.DCN_QUERY_CHANGE_NOTIFICATION,"true");
        OracleConnection c = (OracleConnection)connection;
        DatabaseChangeRegistration dcr = c.registerDatabaseChangeNotification(prop);

        dcr.addListener(new DatabaseChangeListener() {
            @Override
            public void onDatabaseChangeNotification(DatabaseChangeEvent arg0) {
                System.out.println(arg0);
            }
        });
        
        Statement stmt = c.createStatement();
        ((OracleStatement)stmt).setDatabaseChangeRegistration(dcr);
        
        ResultSet rs = stmt.executeQuery("select belongid, employeeid from belongto where belongid=43");
        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.");

        Thread.sleep(40000);
        stmt.close();
        c.unregisterDatabaseChangeNotification(dcr);
        connection.close();
    }
}

とりあえず動けばいいって感じのコードで、色々なところを手抜き工事しているのはかんべんしてください。細かいところはjavadoc参照ということで。OracleConnection (Oracle Database JDBC Java API Reference)

このコードを動かすと何がおきるか。(40000msのスリープしてる間に)SQL Developer等を用いてbelongtoテーブルのbelongid=43行をUPDATEすると以下のような出力がされる。


Connection information : local=localhost/127.0.0.1:47634, remote=localhost/127.0.0.1:2643
Registration ID : 9
Notification version : 1
Event type : QUERYCHANGE
Database name : XE
Query Change Description (length=1)
query ID=3, query change event type=QUERYCHANGE
Table Change Description (length=1): operation=[UPDATE], tableName=KAGAMIHOGE.BELONGTO, objectNumber=20051
Row Change Description (length=1):
ROW: operation=UPDATE, ROWID=AAAE5TAAEAAAAFNAAI

Oracle側から、変更通知対象テーブルの行(ここではselect belongid, employeeid from belongto where belongid=43のこと)に変更があったことがROWID等の情報とともにイベント通知されてるのが分かります。