在 Spring Boot 应用程序中以编程方式重新启动 HikariPool?

Posted

技术标签:

【中文标题】在 Spring Boot 应用程序中以编程方式重新启动 HikariPool?【英文标题】:Programmatically restart HikariPool in Spring Boot application? 【发布时间】:2020-12-06 16:28:52 【问题描述】:

我有一个使用 Hibernate 和 HikariDataSource / HikariPool 与数据库对话的 Spring Boot 应用程序。

应用程序中的一项特殊功能会触发数据库重启。目前这会破坏 HikariPool 中的连接:

Caused by: org.postgresql.util.PSQLException: ERROR: relation "relation_which_really_exists" does not exist
Position: 113
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2532)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2267)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:312)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369)

旧版本的应用程序确实以编程方式调用 org.hibernate.SessionFactory.close();,这会导致 HikariDataSource / HikariCP 重启:

2020-08-17T11:36:42.628Z [qtp1340328248-76] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2020-08-17T11:36:42.698Z [qtp1340328248-76] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2020-08-17T11:36:51.266Z [qtp1340328248-12] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Starting...
2020-08-17T11:36:51.515Z [qtp1340328248-12] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Start completed.

我也想这样做,但是如何以编程方式重新启动我的应用程序中的连接池?我已经看到像Spring Boot - Handle to Hibernate SessionFactory 这样的东西来获取 sessionFactory 的句柄,并且可能类似于获取 DataSource 或 CP 的句柄......但是是否可以暴力关闭/重新启动这些对象,是 Spring Boot 上下文设计器正确处理此类行为?

可能有一些 HikariCP 配置参数我可以开始试验以尝试达到相同的最终结果,但复制旧的实现会成为最容易/最想通和最有可能达到相同最终结果的尝试。

【问题讨论】:

【参考方案1】:

经过一番研究,发现可以通过以下方式获取 HikariCP 的句柄并触发连接驱逐:

    HikariDataSource hikariDs = (HikariDataSource) dataSource;
    HikariPoolMXBean poolBean = hikariDs.getHikariPoolMXBean();
    poolBean.softEvictConnections();

【讨论】:

【参考方案2】:

HikariCP中有一个参数是connectionTestQuery 这是将在池中为您提供连接之前执行的查询,以验证与数据库的连接是否仍然有效。所以我认为你可以用它来检查连接是否仍然存在,然后强制执行。但是他们在文档中提到了这一点“如果您的驱动程序支持 JDBC4,我们强烈建议不要设置此属性。这是针对不支持 JDBC4 Connection.isValid() API 的“旧”驱动程序”

【讨论】:

以上是关于在 Spring Boot 应用程序中以编程方式重新启动 HikariPool?的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 中以编程方式加密/解密数据库密码

在 Spring Boot Transaction 中以只读方式执行 RxJava observable?

在 Windows 中以编程方式复制、重命名和粘贴文件的最佳方法

如何在 Spring 中以编程方式解析属性占位符

Spring Boot 程序化日志配置

如何在 Spring Boot 中以内存高效的方式迭代 MySQL 中的大量记录