为什么Java MySQL连接无法检测到触发器所做的更改?

时间:2012-03-01 06:49:05

标签: java mysql loops triggers database-connection

我有一个问题,需要一些启示......

我使用触发器来检测对数据库所做的更改,这意味着我将所有表设置为带有插入,更新和删除的触发器(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。

实际上这个问题可以通过在循环内部建立连接来解决,但是这会导致另一个问题,因为它会随着循环的消耗而消耗越来越多的资源。 (我已经尝试了这个,它有时会使用我计算机上的所有资源,有时甚至在我已经正确关闭它的时候)

所以有人可以给我一些建议吗?

这是我第一次在这里发帖提问,如果有一些我没有遵守的规则,我很抱歉,请给我正确的方向。

3 个答案:

答案 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();
            }
        }