Hikari 池连接不可用错误

时间:2021-04-02 13:57:59

标签: java spring spring-boot jdbc hikaricp

我的服务器上有一个 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)

1 个答案:

答案 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>