简体   繁体   English

HikariCP 未在 close() 上关闭连接(连接泄漏)

[英]HikariCP not closing connections on close() (Connection Leak)

I'm using HikariCP 3.3.1 and PostgreSQL.我正在使用 HikariCP 3.3.1 和 PostgreSQL。 But I've a problem with closing my connections, in Hikari config I set maximum pool size to 15 and minimum idle connection to 5, but after a few minutes of work with database I've found out connections don't closes, they stack more and more (almost 100 Idle connections right now).但是我在关闭连接时遇到了问题,在 Hikari 配置中,我将最大池大小设置为 15,将最小空闲连接设置为 5,但是在使用数据库几分钟后,我发现连接没有关闭,它们堆叠越来越多(现在几乎有 100 个空闲连接)。 在此处输入图片说明

My Connector class:我的连接器类:

Connector.java连接器.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() {
}
}

And here's my DAO class (simplified): UserDAO.java这是我的 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());
            }
        }
    }
}

Here I've found an issue with some facts about Hikari:在这里,我发现了有关 Hikari 的一些事实的问题:
You must call close() on the connection instance that HikariCP gives you您必须在 HikariCP 为您提供的连接实例上调用 close()

Maybe my dbConnection.close() wont work because it's just a copy of Connection which Hikari gives me in getConnection() method.也许我的dbConnection.close()不起作用,因为它只是 Hikari 在getConnection()方法中给我的 Connection 的副本。

You forgot to close also PreparedStatement你也忘了关闭PreparedStatement

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

Releases this Statement object's database and JDBC resources immediately instead of waiting for this to happen when it is automatically closed.立即释放此 Statement 对象的数据库和 JDBC 资源,而不是等待它自动关闭时发生。 It is generally good practice to release resources as soon as you are finished with them to avoid tying up database resources.通常,在完成资源后立即释放资源是一种很好的做法,以避免占用数据库资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM