在调用PreparedStatement时设置查询超时(以毫秒为单位,而不是秒)?

时间:2013-09-19 15:19:03

标签: java oracle11g timeout

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

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

我正在使用Oracle DB。

3 个答案:

答案 0 :(得分:2)

这非常令人费解,但可以工作:

  1. 有一个ExecutorService
  2. 为查询创建Callable
  3. 将callable提交给ExecutorService
  4. Future<ResultType>将有一个“get(Long, TimeUnit)”函数,阻止到最多设置超时 - 具有可配置的粒度(至少它有望像那样......
  5. 几乎是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)开始...
    • threadpool:如果修复,可能是瓶颈(见上文关注),如果动态:可能是开销

答案 1 :(得分: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,它可以做任何事情并且在#39;

之下。

答案 2 :(得分:0)

我知道这个问题已经过时且PreparedStatement暂停,但有人可能仍然需要解决方案,并且会对整个java.sql.Connection 感到满意,例如:

Executor executor = Executors.newFixedThreadPool(1);
Connection connection = ...
connection.setNetworkTimeout(timeoutExecutor, config.timeout.toMillis.toInt);