Fix connection leak in MySQLMaxValueIncrementer

Move connection cleanup into a finally block so the connection
is closed even if commit or auto-commit restoration fails.

Closes gh-37321

Signed-off-by: cookie-meringue <daehyeon3351@gmail.com>
This commit is contained in:
머랭
2026-10-03 18:36:50 +02:00
committed by GitHub
parent f03b76a53d
commit 5e45b9be1b
2 changed files with 53 additions and 1 deletions
@@ -182,7 +182,9 @@ public class MySQLMaxValueIncrementer extends AbstractColumnMaxValueIncrementer
throw new DataAccessResourceFailureException(
"Unable to commit new sequence value changes for " + getIncrementerName());
}
JdbcUtils.closeConnection(con);
finally {
JdbcUtils.closeConnection(con);
}
}
else {
DataSourceUtils.releaseConnection(con, getDataSource());
@@ -25,8 +25,12 @@ import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.springframework.dao.DataAccessResourceFailureException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -187,6 +191,52 @@ class DataFieldMaxValueIncrementerTests {
verify(connection, times(2)).close();
}
@Test
void mySQLMaxValueIncrementerClosesConnectionOnCommitFailure() throws SQLException {
given(dataSource.getConnection()).willReturn(connection);
given(connection.createStatement()).willReturn(statement);
given(statement.executeQuery("select last_insert_id()")).willReturn(resultSet);
given(resultSet.next()).willReturn(true);
given(resultSet.getLong(1)).willReturn(1L);
willThrow(new SQLException("commit failed")).given(connection).commit();
MySQLMaxValueIncrementer incrementer = new MySQLMaxValueIncrementer();
incrementer.setDataSource(dataSource);
incrementer.setIncrementerName("myseq");
incrementer.setColumnName("seq");
incrementer.afterPropertiesSet();
assertThatExceptionOfType(DataAccessResourceFailureException.class)
.isThrownBy(incrementer::nextLongValue);
verify(connection).commit();
verify(connection).close();
}
@Test
void mySQLMaxValueIncrementerClosesConnectionOnAutoCommitRestoreFailure() throws SQLException {
given(dataSource.getConnection()).willReturn(connection);
given(connection.getAutoCommit()).willReturn(true);
given(connection.createStatement()).willReturn(statement);
given(statement.executeQuery("select last_insert_id()")).willReturn(resultSet);
given(resultSet.next()).willReturn(true);
given(resultSet.getLong(1)).willReturn(1L);
willThrow(new SQLException("autoCommit restore failed")).given(connection).setAutoCommit(true);
MySQLMaxValueIncrementer incrementer = new MySQLMaxValueIncrementer();
incrementer.setDataSource(dataSource);
incrementer.setIncrementerName("myseq");
incrementer.setColumnName("seq");
incrementer.afterPropertiesSet();
assertThatExceptionOfType(DataAccessResourceFailureException.class)
.isThrownBy(incrementer::nextLongValue);
verify(connection).commit();
verify(connection).setAutoCommit(true);
verify(connection).close();
}
@Test
void mariaDBSequenceMaxValueIncrementer() throws SQLException {
given(dataSource.getConnection()).willReturn(connection);