如何在HikariCP中每次请求后正确关闭连接池?
每次请求后关闭HikariCP连接池的实现方案
核心思路
HikariCP的HikariDataSource实现了AutoCloseable接口,可通过调用close()方法直接关闭整个连接池,释放所有池内连接并终止池本身。之前尝试的idle-timeout仅回收池内空闲连接,不会关闭池;try-with-resources仅处理单个数据库资源(连接/语句/结果集),最终还是归还到池,无法关闭池。
修改后的代码实现
import com.zaxxer.hikari.HikariDataSource; import org.springframework.jdbc.core.JdbcTemplate; import java.sql.*; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ReportRequester { private static final Logger log = LoggerFactory.getLogger(ReportRequester.class); private final JdbcTemplate jdbcTemplate; public ReportRequester(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public List<List<Object>> request(String request) { try { // 执行数据库查询逻辑 List<List<Object>> result = jdbcTemplate.execute((Connection connection) -> { List<List<Object>> objectList = new ArrayList<>(); try (PreparedStatement ps = connection.prepareStatement(request); ResultSet rs = ps.executeQuery()) { ResultSetMetaData resultSetMetaData = rs.getMetaData(); while (rs.next()) { List<Object> row = new ArrayList<>(); for (int i = 1; i <= resultSetMetaData.getColumnCount(); ++i) { row.add(rs.getObject(i)); } objectList.add(row); } } catch (SQLException e) { e.printStackTrace(); } return objectList; }); // 执行完成后关闭连接池 HikariDataSource dataSource = (HikariDataSource) jdbcTemplate.getDataSource(); if (dataSource != null && !dataSource.isClosed()) { dataSource.close(); log.info("连接池已成功关闭"); } return result; } catch (Exception e) { log.error("请求处理或连接池关闭失败", e); throw new RuntimeException(e); } } }
关键说明
- 从
JdbcTemplate中获取数据源并强转为HikariDataSource,确保能调用池的关闭方法。 - 关闭连接池后,该
JdbcTemplate对应的数据源会彻底失效,若后续还有请求需求,需要重新创建HikariDataSource和JdbcTemplate实例。 - 此方案仅适用于一次性请求场景(如单次报表生成、临时数据查询),违背了连接池复用连接的设计初衷,非必要场景不建议使用。
内容的提问来源于stack exchange,提问作者Улан Дуйшеналиев
相关产品推荐
相关产品推荐

