From ad46620321e815fb22bed3c81f278cab8fbfe891 Mon Sep 17 00:00:00 2001 From: Alexander Soklakov Date: Tue, 23 Nov 2021 13:28:41 +0400 Subject: [PATCH] Fix for Bug#96900 (30355150), STATEMENT.CANCEL()CREATE A DATABASE CONNECTION BUT DOES NOT CLOSE THE CONNECTION. --- CHANGES | 2 + .../java/com/mysql/cj/jdbc/StatementImpl.java | 13 ++---- .../regression/StatementRegressionTest.java | 42 +++++++++++++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index e4f6b0b6e..3e2fe9936 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ Version 8.0.28 + - Fix for Bug#96900 (30355150), STATEMENT.CANCEL()CREATE A DATABASE CONNECTION BUT DOES NOT CLOSE THE CONNECTION. + - Fix for Bug#104067 (33054827), No reset autoCommit after unknown issue occurs. Thanks to Tingyu Wei for his contribution. diff --git a/src/main/user-impl/java/com/mysql/cj/jdbc/StatementImpl.java b/src/main/user-impl/java/com/mysql/cj/jdbc/StatementImpl.java index 5a6fee421..d841fe1aa 100644 --- a/src/main/user-impl/java/com/mysql/cj/jdbc/StatementImpl.java +++ b/src/main/user-impl/java/com/mysql/cj/jdbc/StatementImpl.java @@ -289,15 +289,14 @@ public void cancel() throws SQLException { } if (!this.isClosed && this.connection != null) { - JdbcConnection cancelConn = null; - java.sql.Statement cancelStmt = null; + NativeSession newSession = null; try { HostInfo hostInfo = this.session.getHostInfo(); String database = hostInfo.getDatabase(); String user = hostInfo.getUser(); String password = hostInfo.getPassword(); - NativeSession newSession = new NativeSession(this.session.getHostInfo(), this.session.getPropertySet()); + newSession = new NativeSession(this.session.getHostInfo(), this.session.getPropertySet()); newSession.connect(hostInfo, user, password, database, 30000, new TransactionEventHandler() { @Override public void transactionCompleted() { @@ -313,12 +312,8 @@ public void transactionBegun() { } catch (IOException e) { throw SQLExceptionsMapping.translateException(e, this.exceptionInterceptor); } finally { - if (cancelStmt != null) { - cancelStmt.close(); - } - - if (cancelConn != null) { - cancelConn.close(); + if (newSession != null) { + newSession.forceClose(); } } diff --git a/src/test/java/testsuite/regression/StatementRegressionTest.java b/src/test/java/testsuite/regression/StatementRegressionTest.java index d9634bedf..abb13ad45 100644 --- a/src/test/java/testsuite/regression/StatementRegressionTest.java +++ b/src/test/java/testsuite/regression/StatementRegressionTest.java @@ -11898,4 +11898,46 @@ public void testBug85223() throws Exception { String value = this.rs.getString(1); assertEquals("LName", value); } + + /** + * Test fix for Bug#96900 (30355150), STATEMENT.CANCEL()CREATE A DATABASE CONNECTION BUT DOES NOT CLOSE THE CONNECTION. + * + * @throws Exception + */ + @Test + public void testBug96900() throws Exception { + assumeTrue(versionMeetsMinimum(5, 6), "MySQL 5.6+ is required to run this test."); + + Properties props = new Properties(); + props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name()); + props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true"); + props.setProperty(PropertyKey.connectionAttributes.getKeyName(), "testBug96900:1"); + + Connection con = getConnectionWithProps(props); + Statement st = con.createStatement(); + new Thread(() -> { + try { + st.executeQuery("SELECT SLEEP(600)"); + } catch (Throwable e) { + e.printStackTrace(); + } + }).start(); + + String attCountQuery = "SELECT COUNT(*) FROM performance_schema.session_connect_attrs WHERE attr_name = 'testBug96900'"; + + this.rs = this.stmt.executeQuery(attCountQuery); + this.rs.next(); + assertEquals(1, this.rs.getInt(1)); + + st.cancel(); + this.rs = this.stmt.executeQuery(attCountQuery); + this.rs.next(); + assertEquals(1, this.rs.getInt(1)); + + con.close(); + this.rs = this.stmt.executeQuery(attCountQuery); + this.rs.next(); + assertEquals(0, this.rs.getInt(1)); + } + }