【问题标题】:How to stop ongoing java.sql.statement.executeQuery()?如何停止正在进行的 java.sql.statement.executeQuery()?
【发布时间】:2015-05-19 16:49:49
【问题描述】:

我正在使用最新的 derby10.11.1.1。 做这样的事情:

DriverManager.registerDriver(new org.apache.derby.jdbc.EmbeddedDriver())
java.sql.Connection connection = DriverManager.getConnection("jdbc:derby:filePath", ...)
Statement stmt = connection.createStatement();
stmt.setQueryTimeout(2); // shall stop query after 2 seconds but id does nothing
stmt.executeQuery(strSql);
stmt.cancel(); // this in fact would run in other thread

我收到异常"java.sql.SQLFeatureNotSupportedException: Caused by: ERROR 0A000: Feature not implemented: cancel"

你知道是否有办法让它工作吗?或者它真的没有在 Derby 中实现,我需要使用不同的嵌入式数据库?关于一些免费数据库的任何提示,我可以使用它来代替 derby 并且支持 SQL 超时?

【问题讨论】:

  • 请显示您的实际代码,而不是“类似”它。如果没有完整的上下文,很难诊断问题。请阅读“How to Ask”了解更多详情。
  • h2 支持查询超时:stackoverflow.com/q/21984515/217324
  • @DougR。我的实际代码有点长。你缺少什么信息?恐怕 Derby 根本不支持 cancel()。我找到了reference manual pagecancel() not supported by the server. 写在哪里所以剩下的问题是如何在没有 cancel() 的情况下解锁 derby 查询,或者使用什么可以取消的嵌入式数据库。
  • 因此,如果它不违反任何保密协议,请发布您的实际代码或导致错误的minimal, complete, and verifiable example

标签: java database jdbc derby


【解决方案1】:

正如我在 java 文档中得到的那样

void cancel() 抛出 SQLException
如果 DBMS 和驱动程序都支持中止 SQL 语句,则取消此 Statement 对象。这个方法可以被一个线程用来取消另一个线程正在执行的语句。

它会抛出

SQLFeatureNotSupportedException - 如果 JDBC 驱动程序不支持此方法

您可以选择mysql。 有很多嵌入式数据库可供您使用 embedded database

【讨论】:

  • 看来mysql需要单独安装mysql服务器。似乎没有免费的嵌入式 mysql。我对吗?我的目标是拥有一个包含 DB 本身的 jar。
  • 是的,您需要为 mysql 安装服务器,然后您需要不同的数据库,如 wikipedia en.wikipedia.org/wiki/Embedded_database
  • 但是他们没有说是否支持 cancel() :(。顺便说一句,除了cancel() 之外还有其他方法可以杀死死锁的事务吗?或者我注定永远不会这样做发生了,我需要关闭整个应用程序?
  • 正如 nathan 告诉 h2 支持的那样。你可以去。
【解决方案2】:

如果你得到Feature not implemented: cancel,那么这是确定的,不支持取消。

this post by H2's author 看来,H2 支持两种超时查询的方法,既通过 JDBC API 也通过 JDBC URL 上的设置。

【讨论】:

  • 是的,在 H2 表中锁超时是默认的,可以由statement.execute("SET LOCK_TIMEOUT 5000");更改
【解决方案3】:

实际上我发现在 derby 中也存在死锁超时,默认情况下只设置为 60 秒,我从来没有耐心达到它:)。

所以正确答案是:

stmt.setQueryTimeout(2); 好像真的不行

stmt.cancel(); 确实似乎没有实现

但幸运的是,数据库管理器中存在超时。并将其设置为 60 秒。见derby dead-locks

可以使用命令更改时间:

statement.executeUpdate("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
                "'derby.locks.waitTimeout', '5')");

它有效:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多