[英]Oracle Data Change Notification Timeout and Workflow
美好時光!
我們在Java應用程序中配置了Oracle DCN功能。 一切正常,但關閉應用程序時會遇到一些麻煩。 如果應用程序意外關閉(例如,通過kill -9
命令kill -9
了tomcat進程),則DCN訂戶將被掛在DB中( select * from user_change_notification_regs;
)。 另外,我可以看到每個訂戶都有4294967295-second
超時。
所以有人可以建議:
1.如何為用戶設置超時時間;
2.為什么即使所有JDBC連接都斷開后訂閱者仍被掛起。 好吧,如果JDBC連接和DCN訂閱之間沒有對應關系,那么當最后一個最終啟動時,oracle如何將DCN發送到java應用程序(從Oracle對應用程序執行任何ping操作,或者類似JMS中的持久訂閱)?
更新 :我已經找到了第一點的答案。 可以為DatabaseChangeRegistration
設置OracleConnection.NTF_TIMEOUT
參數:
Properties properties = new Properties();
properties.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS, "true");
properties.setProperty(OracleConnection.DCN_BEST_EFFORT, "true");
properties.setProperty(OracleConnection.NTF_TIMEOUT, "3600");
DatabaseChangeRegistration databaseChangeRegistration = oracleConnection.registerDatabaseChangeNotification(properties);
由於DBMS無法跟蹤需要心跳機制的“准備該連接的JDBC連接仍然有效” ,因此必須明確刪除user_change_notification_regs
表中保留的記錄。 因此,當服務器重新啟動時,您必須顯式刪除(注銷)這些記錄。 這是一個例子。
try (Connection conn = ConnManager.getConnection();) {
if (conn.isWrapperFor(OracleConnection.class)) {
try (OracleConnection oracleConnection = conn.unwrap(OracleConnection.class);
Statement stmt = oracleConnection.createStatement()) {
ResultSet rs = stmt.executeQuery("select regid,callback from USER_CHANGE_NOTIFICATION_REGS");
while (rs.next()) {
long regid = rs.getLong(1);
String callback = rs.getString(2);
((OracleConnection) stmt.getConnection()).unregisterDatabaseChangeNotification(regid, callback);
}
}
}
} catch (SQLException ex) {
Logger.getLogger(TableBase.class.getName()).log(Level.SEVERE, null, ex);
}
您可以簡單地將此代碼放在將只執行一次的類的靜態塊或初始化方法中。 如果為偵聽器設置超時,則oracle服務器端驅動程序會為您的連接啟用心跳機制,這可能會稍微降低應用程序性能。
Oracle最終將清理無效的注冊。 您還可以在服務器端的sqlnet參數文件中啟用保持活動狀態,以加快此清理過程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.