This is an automated email from the ASF dual-hosted git repository.

terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 95057377850 Skip cancellation of closed Statements during proxy 
cleanup (#40090)
95057377850 is described below

commit 95057377850f9c3a142fa45486efeb82c33e7991
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Oct 7 15:19:55 2026 +0800

    Skip cancellation of closed Statements during proxy cleanup (#40090)
    
    * Refactor DataSourcePoolCreatorTest
    
    * Skip cancellation of closed Statements during proxy cleanup
---
 .../connector/StandardDatabaseProxyConnector.java  | 12 +++++++++-
 .../StandardDatabaseProxyConnectorTest.java        | 27 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
index b40aeaae72e..72ec5d6de9c 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
@@ -397,7 +397,9 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
                 continue;
             }
             try {
-                each.cancel();
+                if (!isClosed(each)) {
+                    each.cancel();
+                }
                 each.close();
             } catch (final SQLException ex) {
                 result.add(ex);
@@ -411,6 +413,14 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
         return statement instanceof PreparedStatement && 
databaseConnectionManager.getConnectionSession().getPreparedStatementCacheContext().contains(statement);
     }
     
+    private boolean isClosed(final Statement statement) {
+        try {
+            return statement.isClosed();
+        } catch (final SQLException ignored) {
+            return false;
+        }
+    }
+    
     private Optional<SQLException> closeSQLFederationEngine() {
         if (null != proxySQLExecutor.getSqlFederationEngine()) {
             try {
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
index a44d45d0f2d..7a903175c40 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
@@ -124,8 +124,10 @@ import java.util.stream.IntStream;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.isA;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -754,6 +756,31 @@ class StandardDatabaseProxyConnectorTest {
         verify(statement).close();
     }
     
+    @Test
+    void assertCloseWithClosedStatement() throws SQLException {
+        DatabaseProxyConnector engine = 
createDatabaseProxyConnector(JDBCDriverType.STATEMENT, 
createQueryContext(createSQLStatementContext(new SQLStatement(databaseType)), 
mockDatabase()));
+        when(statement.isClosed()).thenReturn(true);
+        doThrow(new SQLException("Statement is 
closed")).when(statement).cancel();
+        engine.add(statement);
+        engine.close();
+        verify(statement, never()).cancel();
+        verify(statement).close();
+    }
+    
+    @Test
+    void assertCloseWithStatementClosedCheckFailure() throws SQLException {
+        DatabaseProxyConnector engine = 
createDatabaseProxyConnector(JDBCDriverType.STATEMENT, 
createQueryContext(createSQLStatementContext(new SQLStatement(databaseType)), 
mockDatabase()));
+        when(statement.isClosed()).thenThrow(new SQLException("Statement 
state"));
+        SQLException expected = new SQLException("Statement");
+        doThrow(expected).when(statement).close();
+        engine.add(statement);
+        SQLException actual = assertThrows(SQLException.class, engine::close);
+        verify(statement).cancel();
+        verify(statement).close();
+        assertThat(actual.getNextException(), sameInstance(expected));
+        assertNull(actual.getNextException().getNextException());
+    }
+    
     @Test
     void assertCloseSkipCachedPreparedStatement() throws SQLException {
         DatabaseProxyConnector engine = 
createDatabaseProxyConnector(JDBCDriverType.STATEMENT, 
createQueryContext(createSQLStatementContext(new SQLStatement(databaseType)), 
mockDatabase()));

Reply via email to