Следующий код запускает предупреждение о утечке соединения. Я использую OpenJDK 1.7.0_80 и HikariCP 2.2.5 (также воспроизводимый с последним HikariCP 2.3.9). Я что-то упускаю?Утечка соединения с помощью try-with-resources и HikariCP
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.junit.Test;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class HikaryAutoCloseTest {
private static HikariDataSource configureDataSource() {
try {
Class.forName("org.postgresql.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://127.0.0.1/DATABASE");
config.setUsername("USERNAME");
config.setPassword("PASSWORD");
config.setLeakDetectionThreshold(10000);
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("useServerPrepStmts", "true");
return new HikariDataSource(config);
}
@Test
public void testHikaryAutoClose() {
HikariDataSource dataSource = configureDataSource();
boolean ret = shouldNotLeakConnection(dataSource);
if (ret) {
System.out.println("UPDATE okey");
}
/* Wait for LeakTask to complain */
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("Exiting");
}
private boolean shouldNotLeakConnection(HikariDataSource dataSource) {
String sql = "INSERT INTO error_logs (description) values (?)";
try (Connection conn = dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql);) {
stmt.setString(1, "description");
return stmt.executeUpdate() != 0; // minor changes to this line remove the leak
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
UPDATE: Слегка изменив оператор возврата исключает утечку:
private boolean shouldNotLeakConnection(HikariDataSource dataSource) {
String sql = "INSERT INTO error_logs (description) values (?)";
try (Connection conn = dataSource.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql);) {
stmt.setString(1, "description");
boolean ret = stmt.executeUpdate() != 0;
return ret;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
На первый взгляд это выглядит хорошо. Я должен сам запустить этот тест утром, но я скажу, что эти свойства DataSource предназначены для MySQL не PostgreSQL. Что произойдет, если вы закрываете соединение явно? – brettw
@brettw Явным образом вызов 'conn.close()' также решает проблему утечки, но он игнорирует всю цель try-with-resources и компилятор заботится о надлежащем закрытии ресурсов. – user1202136
Я понятия не имею, что происходит с вашей средой, но я запустил приведенный выше код (без изменений) под Eclipse с веткой HikariCP dev и под IntelliJ с HikariCP 2.3.9, и оба выполнялись без регистрации исключения утечки. – brettw