6

有没有办法以毫秒而不是秒为单位设置查询超时?java.sql.Statement API 只有几秒钟的方法,但对于我的用例来说,即使是 1 秒也太慢了。

Java API:http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#setQueryTimeout(int)

我正在使用 Oracle 数据库。

4

3 回答 3

3

这是相当复杂的,但可以工作:

  1. 有一个 ExecutorService
  2. 为查询创建一个 Callable
  3. 将 callable 提交给 ExecutorService
  4. Future<ResultType>有一个“ get(Long, TimeUnit) ”函数,最多阻塞到设置的超时时间——它具有可配置的粒度(至少它承诺是那样的......

在几乎 Java 代码中是这样的:

public class MyCallable implements Callable<ResultType> {
  @Override
  public ResultType call() throws Exception {
    //do query, with 1s timeout - that way no thread will be busy for more than 1s
    return result;
  }
}

处理请求

ExecutorService threadPool; //initialised somewhere earlier

Future<ResultType> futureResult = threadPool.submit(new MyCallable());
try {
    ResultType result = futureResult.get(100, TimeUnit.MILLISECONDS);
    //results received in time, do the processing here
} catch(TimeoutException e) {
    //request too slow -- handle it
} catch( other exceptions...) { ... }

关注点:

  • 我不知道这意味着多少开销......
  • 超时:我不知道他们将如何处理。
  • 超时的请求将被卡在线程池中,直到内部的 JDBC 超时 (1s) 开始...
  • 线程池:如果固定,可能是瓶颈(参见上面的问题),如果动态:可能是开销
于 2013-09-19T16:18:18.203 回答
0

我意识到这个线程很老了,但我几天前才偶然发现它,同时我找到了一个更好的解决方案。

仅适用于 Oracle DB:

您可以设置此属性: oracle.jdbc.ReadTimeout

根据Oracle的文档,它表示:从套接字读取时读取超时。这仅影响瘦驱动程序。超时以毫秒为单位。

文档 http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/jdbc/pool/OracleDataSource.html

这与 Statement 的超时实现略有不同,后者导致查询正常停止,但在我的情况下,这就是我所需要的。

不确定它是否会切断连接。我正在使用 c3p0 ,它可以“在引擎盖下”完成所有操作。

于 2015-12-23T10:06:14.623 回答
0

我知道这个问题很老而且关于PreparedStatement超时,但有人可能仍然需要解决方案,并且会对整个解决方案感到满意java.sql.Connection例如:

Executor executor = Executors.newFixedThreadPool(1);
Connection connection = ...
connection.setNetworkTimeout(timeoutExecutor, config.timeout.toMillis.toInt);
于 2017-05-02T12:27:31.443 回答