我有一个问题,需要一些启示......
我使用触发器来检测对数据库所做的更改,这意味着我将所有表设置为带有插入,更新和删除的触发器(MySQL)
然后我将该更改写入我专门用于包含有关更改的所有信息的表中。我们把它命名为xtable。 (此表未配备触发器)
我的Java程序需要不断读取xtable,让其他应用程序知道更改。
问题是,当我在循环中读取xtable时,我只能读取xtable的初始值,即我建立与数据库的连接时的初始值。 (连接在循环外建立)
如果对数据库进行了更改,这将导致xtable中的新行,无论我通过执行“select * from xtable”查询读取多少次,都不会检测到触发器生成的这一新行..
代码如下所示:
public static void main(String[] args) {
Connection conn = null;
try {
conn = database.getConnection();
Statement state = conn.createStatement();
String query = "select * from `xtable`;";
while (true) {
ResultSet rs = state.executeQuery(query);
while(rs.next){
// Some code for letting the other application know of the change
}
}
} catch (SQLException ex) {
} finally {
if (conn != null) {
conn.close();
}
}
}
所以基本上如果我在xtable为空时运行程序,即使有时候有新行,我总是得到一个空的ResultSet。
实际上这个问题可以通过在循环内部建立连接来解决,但是这会导致另一个问题,因为它会随着循环的消耗而消耗越来越多的资源。 (我已经尝试了这个,它有时会使用我计算机上的所有资源,有时甚至在我已经正确关闭它的时候)
所以有人可以给我一些建议吗?
这是我第一次在这里发帖提问,如果有一些我没有遵守的规则,我很抱歉,请给我正确的方向。
答案 0 :(得分:1)
有事务隔离这样的事情。您的连接可能没有看到更改,因为您没有提交来自触发器的事务,或者您没有在客户端启动新连接。没有看到您的数据库设置就无法判断。
PS:消息队列是更好的替代方法
答案 1 :(得分:0)
我认为你最好考虑触发而不是通过循环查询DBMS。
如果使用触发器,则不必使用Java端的'while'循环来检查DB的更改 相反,嵌入在DBMS中的触发机制将在发生更改时通知Java端。
对于Oracle,您可以从PL / SQL调用Java方法 对于PostgreSQL,您可以从PL / Java调用Java方法 对于CUBRID,您可以从Java存储过程调用Java方法。
对于MySQL,您可以调用Java方法,但我认为它不像上面那么容易
我希望这个链接可以帮到你。 http://code.rocksol.it/call-java-from-mysql-trigger
或谷歌这个关键字,“mysql java用户定义函数”
答案 2 :(得分:0)
Connection connection=getConnection();
statement="query";
try {
stmt = connection.prepareStatement(statement);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (connection != null && stmt != null) {
stmt.close();
}
}