java – MySQL查询中的LIMIT如何使取消流成为可能

我想知道查询中的LIMIT如何阻止从MySQL流中读取的应用程序线程在关闭操作中挂起,以及为什么限制启用查询取消否则无效.Statement statement = connection.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, jav...

我想知道查询中的LIMIT如何阻止从MySQL流中读取的应用程序线程在关闭操作中挂起,以及为什么限制启用查询取消否则无效.

    Statement statement = connection.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
    statement.setFetchSize(Integer.MIN_VALUE);

// Statement statement = connection.createStatement(); // this can be canceled

    new Thread(new Runnable() {

        // tries to cancel query after streaming starts
        @Override
        public void run() {
            try {
                Thread.sleep(5);
                statement.cancel(); // does nothing when streaming
               // statement.close(); // makes application thread hang
            } catch (SQLException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();

    // adding limit to the query makes it possible to cancel stream, even if limit is not yet reached
    resultSet = statement.executeQuery("SOME_LONG_RUNNING_QUERY");

    int i = 0;
    while (resultSet.next()) {
        System.out.println(++i);
    }

    connection.close(); 

可以安全地取消常规(非流式)查询,有或没有限制.然而,在流模式下,关闭/取消操作只会使应用程序线程挂起/不执行任何操作,可能是在对套接字执行阻塞读取时.

如果我向长时间运行的查询添加一些大的LIMIT,那么,正如预期的那样,cancel()操作结果为:

com.mysql.jdbc.exceptions.jdbc4.MySQLQueryInterruptedException: Query execution was interrupted

我理解这个问题有几个问题,但没有一个讨论下面的方面:

>为什么LIMIT可以取消流式查询
>可以依赖这个bug功能,可以在下一个版本中更改,有任何官方解释吗?

解决方法:

限制make只是从数据库中提取了一定数量的记录.限制很有用,如果您有一个可以挂起的大型查询,则最好使用限制.

在您的情况下,当您传输具有limit和close语句的查询时,它遵循操作顺序.由于LIMIT首先出现,因此结果将结束您的查询.这可以解释为什么即使你有一个密切的声明它也没有达到它以及你收到异常的原因.

我希望这能解决你遇到的一些问题.

本文标题为:java – MySQL查询中的LIMIT如何使取消流成为可能

基础教程推荐