【问题标题】:Killing query created by another application杀死另一个应用程序创建的查询
【发布时间】:2014-07-17 06:54:40
【问题描述】:

我有一个 Java 应用程序,我希望能够终止对多个数据库的查询。我知道如何获取 information_schema.processlist 中的查询,但问题是我不知道如何终止这些查询。通常我会使用 KILL 命令来执行此操作,但我不能在 java 应用程序中使用它(或者至少我还没有弄清楚如何去做)。

我一直在阅读 Statement.cancel,但问题是查询是由另一个应用程序创建的。我知道您必须在要取消它的类中有 Statement 变量。

如果我可以为此目的使用声明,有人可以帮我理解如何。我正在使用 MySQL 数据库。我不想设置超时,因为我希望能够杀死任何我想要的查询。

这些是我尝试终止进程的一些示例:

public synchronized void killProcesses(Set<Long> ids) {
    for (long id : ids) {
        String killCommand="Select 'KILL ' from processlist where id=:id";

        Query query= queryManager.createQuery(killCommand);
        query.setParameter("id", id);
        query.getResultList();
    }
}

public synchronized void killProcesses(Set<Long> ids) {
    for (long id : ids) {
        String killCommand="KILL " + id;

        Query query= queryManager.createQuery(killCommand);
        query.getResultList();
    }
}

【问题讨论】:

  • 第二次尝试的问题/错误信息是什么?我认为您应该尝试Statement.executeUpdate() 而不是尝试getResultList()
  • @HannoBinder 我得到的异常是:异常描述:语法错误解析 [KILL QUERY71427]。 [0, 15] 查询不以有效标识符开头,必须是 SELECT、UPDATE 或 DELETE FROM。
  • 使用Statement.execute() 执行任意SQL。正如异常所说,您使用的方法仅支持选择、更新或删除
  • 我尝试了query.executeUpdate(),但得到了几乎相同的异常。 Statement的问题是我使用entityManager,所以我不能crete Statement,但我想我会尝试解开连接并用它创建Statement。
  • 我试图解开连接并创建和执行语句,但我得到了空指针。 queryManager.unwrap(Connection.class) 似乎返回 null。我首先认为这是因为我总是在事务后关闭连接,但我从我的 persistence.xml 中删除了它,它仍然无法正常工作。我正在使用 Eclipselink。

标签: java mysql sql database kill


【解决方案1】:

@HannoBinder 解决了问题,最终解决方案是:

private String killQuery(long id) {
    String killCommand="KILL " + id;
    queryManager.getTransaction().begin();
    Query query=queryManager.createNativeQuery(killCommand);
    query.executeUpdate();
    queryManager.getTransaction().commit();
    return "OK";
}

还有一个也有效,但没那么简单:

public synchronized void killProcesses(Set<Long> ids) {
    for (long id : ids) {
        String killCommand="KILL QUERY " + id;
        queryManager.getTransaction().begin();
        Connection conn=queryManager.unwrap(Connection.class);
        try {
            Statement statement= conn.createStatement();
            statement.execute(killCommand);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
                queryManager.getTransaction().commit();
                conn.close();   
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多