HikariCP (пул соединений) перестает выдавать соединения
Всем привет, столкнулся с проблемой в которой не могу разобраться. Подключил HikariCP, пользователей приложения около 50 человек, ~ через час пул соединений перестает выдавать соединения (HikariPool-1 - Connection is not available, request timed out after 3000ms.) Задавал разные настройки и тайминги, но проблема не исчезает, единственное что я придумал это создавать принудительно нативное соединение(но оно долго создается и интерфейс приложения подтормаживает). БД - PostgreSQL
Вот мой код:
public enum MyConnectionPool {
INSTANCE();
private HikariDataSource dataSource;
MyConnectionPool() {
if(dataSource==null) {
HikariConfig config = new HikariConfig();
config.setDriverClassName(ConnectionProperty.DRIVER_NAME.getValue());
config.setJdbcUrl(ConnectionProperty.URL.getValue());
config.setUsername(ConnectionProperty.LOGIN.getValue());
config.setPassword(ConnectionProperty.PASS.getValue());
config.addDataSourceProperty("dataSource.cachePrepStmts","true");
config.addDataSourceProperty("dataSource.prepStmtCacheSize","250");
config.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit","2048");
/*Перепробовал кучу параметров */
config.setMaximumPoolSize(80);
config.setMinimumIdle(30);
config.setIdleTimeout(0);
config.setConnectionTimeout(3000);//3 секунды
config.setMaxLifetime(0);
config.setKeepaliveTime(60000);//10мин
config.setLeakDetectionThreshold(2000);
dataSource = new HikariDataSource(config);
}
}
public Connection getConn(){
if(dataSource!=null) {
try {
return dataSource.getConnection();
} catch (SQLException e) {
try {
Notification.show("Не получил соединение из пула, создал новое:"+e.getMessage());
}catch (Exception e1){
}
//~ через час начинает срабатывать принудительное создание подключения и начинаются тормоза
return CRMDatabaseConnection.getDatabaseConnection();
}
}else {
try {
Notification.show("dataSource IS NULL, создал новое соединение");
}catch (Exception e1){
}
return CRMDatabaseConnection.getDatabaseConnection();
//return null;
}
}
public HikariDataSource getDataSource() {
return dataSource;
}
}
Обращаюсь к базе вот таким способом:
try(Connection connection = MyConnectionPool.INSTANCE.getConn()){
String sql = "SELECT .................."
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
.....................
}
rs.close;
stmt.close;
}catch (Exception e){
}
Такое ощущение что пул создает соединения, после того как я использую соединение я его закрываю, соединение в пуле становится закрытым, и при повторном обращении к пулу он мне и выдает закрытое соединение. Хотя по логике connection (это HikariProxyConnection), и закрывая его я по cути говорю пулу, что соединение может использовать кто то другой, т.е физически оно не должно закрываться
Делаю тесты:
int counter = 0;
for(int i=0;i<1000;i++) {
try (Connection connection = MyConnectionPool.INSTANCE.getConn()) {
System.out.println(connection);
String sql = "SELECT COUNT(1) AS COUNT from sys_leads LIMIT 100";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()){
int count = rs.getInt("COUNT");
System.out.println(count);
counter++;
}
rs.close();
stmt.close();
} catch (Exception e) {
System.out.println("ошибка:"+e);
}
System.out.println("итерация:"+counter);
}
Пул возвращает одно и тоже соединение и как бы все нормально, ошибок нет. Если реализовать этот код в разных потоках то тоже все нормально, на каждый поток возвращается свое соединение и проблем нет