Bug #103796 Connector/J 8 stmt setQueryTimeout can not work
Submitted: 25 May 2021 3:06 Modified: 24 Sep 2021 21:24
Reporter: hong wang (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:8.0.21, 8.0.25 OS:Any
Assigned to: CPU Architecture:Any

[25 May 2021 3:06] hong wang
Description:
Connector/J 8 stmt setQueryTimeout can not work when use custor.

How to repeat:
###DDL

CREATE DATABASE IF NOT EXISTS test DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;

CREATE TABLE `test_001` (
  `fid` bigint(20) DEFAULT NULL,
  `ftext` longtext COLLATE utf8mb4_unicode_ci
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

INSERT INTO test.test_001 (fid,ftext) VALUES
	 (1,'323232'),
	 (2,'fdsafdsa');

###JAVA CODE

public static Connection getConnWithUseCursor() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Set<String> prop = new HashSet<>();
        prop.add("useUnicode=true");
        prop.add("characterEncoding=UTF-8");
        prop.add("serverTimezone=Asia/Shanghai");
        prop.add("useCursorFetch=true");
        prop.add("defaultFetchSize=100");
        prop.add("useServerPrepStmts=true");
        prop.add("allowMultiQueries=true");
        prop.add("useUsageAdvisor=false");
        return DriverManager.getConnection("jdbc:mysql://192.168.56.102:3306/test?" + String.join("&", prop), "root", "123456");
}

public void stmtExecuteQuery() {
        String sql = "select * from temp_001 t where fid in (select sleep(5))";
        Connection conn = null;
        long start = System.currentTimeMillis();
        try{
            conn = getConnWithUseCursor();
            Statement stmt = conn.createStatement();
            stmt.setQueryTimeout(3);
            start = System.currentTimeMillis();
            stmt.executeQuery(sql);
        } catch (SQLException | ClassNotFoundException ex) {
            ex.printStackTrace();
        }finally {
            close(conn);
            System.out.println("stmt execute query cost:" + (System.currentTimeMillis() - start));
        }
}

public void preStmtExecuteQuery() {
        String sql = "select * from temp_001 t where fid in (select sleep(5))";
        Connection conn = null;
        long start = System.currentTimeMillis();
        try{
            conn = getConnWithUseCursor();
            PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setQueryTimeout(3);
            start = System.currentTimeMillis();
            stmt.executeQuery();
        } catch (SQLException | ClassNotFoundException ex) {
            ex.printStackTrace();
        }finally {
            close(conn);
            System.out.println("cost:" + (System.currentTimeMillis() - start));
        }
}

private void close(AutoCloseable closeable) {
    try{
        if (closeable != null) {
            closeable.close();
        }
    } catch (Exception ignored) {
    }
}

public static void main(String[] args) {
    stmtExecuteQuery();
    preStmtExecuteQuery();
}

### RESULT

stmtExecuteQuery() can not get query timeout,but preStmtExecuteQuery() ok.

Suggested fix:

in MySQL Connector/j 8.0.21.
When use cursor,

com.mysql.cj.jdbc.StatementImpl#createResultSetUsingServerFetch create new PreparedStatement to replaced Statement to executeQuery,but not set queryTimeout.
[25 May 2021 7:00] MySQL Verification Team
Hello hong wang,

Thank you for the report and test case.

regards,
Umesh
[25 May 2021 18:39] OCA Admin
Contribution submitted via Github - Fix for Bug#103796,Connector/J 8 stmt setQueryTimeout can not work when use curs 
(*) Contribution by hong wang (Github jincarry567, mysql-connector-j/pull/63#issuecomment-847957196): I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: git_patch_652291761.txt (text/plain), 1.25 KiB.

[24 Sep 2021 21:24] Daniel So
Posted by developer:
 
Added the following entry to the Connector/J 8.0.27 changelog: 

"setQueryTimeout() failed to set a timeout for queries when a cursor was used for fetching rows. Thanks to Hong Wang for contributing the fix. "