我的服务器上有一个 Spring Boot 项目。我有时会遇到“Hikari 池连接不可用”错误。我无法弄清楚它的原因。我看起来很多这样的问题。有人建议关闭一些@Transactions。但是,在我的应用程序中,我没有使用任何 @Transactional 注释。这是我的 Hikari 池配置:
# hikari settings
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.maximumPoolSize=10
# hikari log
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.com.zaxxer.hikari=TRACE
当我检查 catalina.out 日志文件时,我注意到活动连接数有时会增加。例如,昨天没有活动连接。所有连接都处于空闲状态。现在池中有 2 个活动连接。我收到此错误是否是因为连接池由所有活动连接填充?
顺便说一下,我使用的是 MySQL 数据库。我应该将 maxLifeTime 设置为比 mysql wait_timeout 少一两秒吗?我问这个问题是因为根据 https://github.com/brettwooldridge/HikariCP,maxLifeTime 应该比任何数据库或基础设施强加的连接时间限制短几秒。您认为 maxLifeTime 与 wait_timeout 有关系吗?
这是错误的堆栈跟踪:
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:48)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:109)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:136)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:50)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2082)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2012)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1990)
at org.hibernate.loader.Loader.doQuery(Loader.java:949)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:351)
at org.hibernate.loader.Loader.doList(Loader.java:2787)
at org.hibernate.loader.Loader.doList(Loader.java:2770)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2604)
at org.hibernate.loader.Loader.list(Loader.java:2599)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2254)
at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1069)
at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:170)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1506)
... 116 more
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30001ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:676)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:190)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:155)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128)
答案 0 :(得分:0)
根据您的描述,一个可能的原因是您的数据连接超过最大池大小(设置为 10)。根本原因可能是代码中的连接泄漏。您是否正确关闭了连接?要么明确关闭它:
statement.close();
connection.close();
或
try (Connection connection = ***;
PreparedStatement statement = *** )
catch (SQLException ex) {***}
如果是这种情况,您可以启用 Hikari 日志来检查。 logback.xml
<logger name="com.zaxxer.hikari" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>