HikariCP не закрывает соединения при закрытии () (утечка соединения) - PullRequest
1 голос
/ 26 мая 2019

Я использую HikariCP 3.3.1 и PostgreSQL. Но у меня проблема с закрытием соединений, в конфиге Hikari я установил максимальный размер пула 15 и минимальное бездействующее соединение 5, но после нескольких минут работы с базой данных я обнаружил, что соединения не закрываются, они складываются все больше и больше (почти 100 свободных соединений прямо сейчас). enter image description here

Класс My Connector:

Connector.java

public class Connector implements IConnector {
private static HikariConfig config = new HikariConfig();
private static HikariDataSource ds;

static {
    config.setDriverClassName(org.postgresql.Driver.class.getName());
    config.setJdbcUrl("jdbc:postgresql://localhost:5432/vskDB");
    config.setUsername("postgres");
    config.setPassword("root");
    config.setMinimumIdle(5);
    config.setMaximumPoolSize(15);
    config.setConnectionTimeout(20000);
    config.setIdleTimeout(300000);
    ds = new HikariDataSource(config);
}

public Connection getConnection() {
    log.info("getConnection() invoked");
    try {
        return ds.getConnection();
    } catch (SQLException e) {
        log.error("Can't get connection from DataSource.");
        log.error(e.getMessage());
        System.out.println(e.getMessage());
    }
    return null;
}

Connector() {
}
}

А вот мой класс DAO (упрощенно): UserDAO.java

public class UserDatabaseDAO implements UserDAO {
    private Connector connector = new Connector();
    private Connection dbConnection;

    @Override
    public void removeUser(Long id) {
        try {
            dbConnection = connector.getConnection();
            if (dbConnection == null)
                throw new ConnectException();

            PreparedStatement preparedStatement = dbConnection.prepareStatement("DELETE FROM users WHERE user_id = ?");
            preparedStatement.setLong(1, id);
            preparedStatement.execute();

        } catch (SQLException | ConnectException e) {
            log.error("Can't remove user from database");
            log.error(e.getMessage());
            System.out.print(e.getMessage());
        } finally {
            try {
                dbConnection.close();
            } catch (SQLException e) {
                log.error("Can't close connection");
                log.error(e.getMessage());
                System.out.print(e.getMessage());
            }
        }
    }
}

Здесь Я обнаружил проблему с некоторыми фактами о Хикари:
Вы должны вызвать close () для экземпляра соединения, который вам дает HikariCP

Может быть, мой dbConnection.close() не будет работать, потому что это просто копия Connection, которую Хикари дает мне в методе getConnection().

1 Ответ

2 голосов
/ 27 мая 2019

Вы забыли закрыть также PreparedStatement

try {
       if (preparedStatement== null) {
            preparedStatement.close();
       }
       if (dbConnection == null) {
            dbConnection.close();
       }

Освобождает базу данных этого объекта Statement и ресурсы JDBC немедленно, вместо того, чтобы ждать, пока это не произойдет, когда он будет автоматически закрыт. Обычно рекомендуется освобождать ресурсы, как только вы закончите с ними, чтобы не связывать ресурсы базы данных.

...