How do I properly close a HikariCP Connection Pool
Asked Answered
T

1

14

I'm using HikariDataSource to connect to a MariaDB database. The following class returns a Connection.

public class DataSource {

private HikariDataSource ds;

// The constructor takes db name as an argument and creates a new datasource for the connection accordingly.
public DataSource(String dbString) {
    HikariConfig config = new HikariConfig();
    Map map = DbConfigParser.configKeyValue(dbString);
    config.setJdbcUrl(String.valueOf(map.get("uri")));
    config.setUsername(String.valueOf(map.get("uname")));
    config.setPassword(String.valueOf(map.get("pwd")));
    config.addDataSourceProperty("cachePrepStmts", "true");
    config.addDataSourceProperty("prepStmtCacheSize", "250");
    config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
    ds = new HikariDataSource(config);
}

// Returns a Connection to the database
public Connection getConnection() throws SQLException {
    return ds.getConnection();
}

// Close the datasource
public void close(){
    if (ds != null) {
        ds.close();
    }
  }
}

This is the method that executes the select query. The class also contains a close method

public List<DataFile> getAllFiles() throws SQLException {
try (Connection connection = dataSource.getConnection();
    DSLContext ctx = DSL.using(connection, SQLDialect.MARIADB)) {
  List<DataFile> dataFileList = new DataFileQueries().selectQuery(ctx)
      .fetchInto(DataFile.class);
  if (dataFileList == null || dataFileList.isEmpty()) {
    throw new IllegalStateException("The List is Empty!");
  }
  return dataFileList;
   }
}

public void close() {
try {
  dataSource.close();
} catch (Exception e) {
  LOG.error("A SQLException was caught", e);
 }
}

The try-with-block closes the Connection object automatically, but how do I close the connection pool? Should I call the call the close method after the database operation, for example

public static void main(String[] args) throws SQLException {
DataFileDaoImpl service = new DataFileDaoImpl("testi");
List<DataFile> list = service.getAllFiles();
list.stream().forEach(
    e -> System.out.println(e.toString())
);
service.close();
}

When I don't call the close() method, I don't see any console output regarding shutdown initiation. Is this the right way to close HikariDataSource and Connection Pool?

Tyronetyrosinase answered 17/2, 2019 at 11:2 Comment(0)
P
18

You don't need to call DataSource's close() for every connection:

Shutdown the DataSource and its associated pool.

It's defined only for application termination:

close() is essential at application termination

You should continue working with the pool, notice you are closing (correctly) the connection with try with resources

try (Connection connection = dataSource.getConnection()
Polymerism answered 17/2, 2019 at 11:11 Comment(3)
Thank you very much for your explanation. So, it's okay to call close() only during the application termination and not after every Connection is closed?Tyronetyrosinase
@RoshanUpreti yesPolymerism
@RoshanUpreti If you close the data source after each connection, you throw away any benefit a connection pool has (not to mention that you might break concurrent use of connections checked out of the pool).Perkoff

© 2022 - 2024 — McMap. All rights reserved.