Oracle UCP maxConnectionReuseTime配置异常:闲置连接Stale问题排查
环境信息
- Oracle服务器 v19c
- 使用
com.oracle.database.jdbc:ojdbc10-production:19.29.0.0中的JDBC驱动与UCP - 基于Tomcat10/Java17/SpringBoot3.5的应用
- 已启用UCP日志,配置
oracle.ucp.level = FINEST - 应用服务器与数据库服务器之间的防火墙超时时间为3600秒
- 在Tomcat10的context.xml中定义了JNDI数据源
<Resource name="jdbc/bo" auth="Container" type="oracle.ucp.jdbc.PoolDataSource" factory="oracle.ucp.jdbc.PoolDataSourceImpl" connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource" url="jdbc:oracle:thin:@NNN:1521:mapps" user="nnn" password="nnn" inactiveConnectionTimeout="20" maxConnectionReuseTime="1800" abandonedConnectionTimeout="60" minPoolSize="2" maxPoolSize="50" connectionPoolName="UCPPool0" validateConnectionOnBorrow="true" sqlForValidateConnection="select 1 from DUAL" connectionProperties="defaultNChar=true" />
问题现象
当Tomcat服务器闲置一段时间(超过60分钟)后,连接池中的2个连接均变为stale状态。在UCP日志中可看到2条疑似验证查询超时的记录:
15-Nov-2025 08:19:43.462 FINEST [ajp-nio-10.1.240.221-8009-exec-6] oracle.ucp.logging.ClioSupport._log :::throwing: null : [ oracle.ucp.util.UCPTaskManagerImpl$5.get(UCPTaskManagerImpl.java:263), oracle.ucp.common.UniversalPooledConnectionImpl.isValidHelper(UniversalPooledConnectionImpl.java:361), oracle.ucp.common.UniversalPooledConnectionImpl.isValid(UniversalPooledConnectionImpl.java:323), oracle.ucp.common.FailoverableUniversalPooledConnectionBase.isValid(FailoverableUniversalPooledConnectionBase.java:17), oracle.ucp.jdbc.oracle.OracleUniversalPooledConnection.isValid(OracleUniversalPooledConnection.java:242), oracle.ucp.common.UniversalConnectionPoolImpl.borrowConnectionAndValidateHelper(UniversalConnectionPoolImpl.java:202), oracle.ucp.common.UniversalConnectionPoolImpl.borrowConnectionAndValidate(UniversalConnectionPoolImpl.java:154), oracle.ucp.common.UniversalConnectionPoolImpl.borrowConnection(UniversalConnectionPoolImpl.java:127), oracle.ucp.jdbc.JDBCConnectionPool.borrowConnection(JDBCConnectionPool.java:174), oracle.ucp.jdbc.oracle.OracleJDBCConnectionPool.borrowConnection(OracleJDBCConnectionPool.java:624), oracle.ucp.jdbc.oracle.OracleConnectionConnectionPool.borrowConnection(OracleConnectionConnectionPool.java:106), oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:2037), oracle.ucp.jdbc.PoolDataSourceImpl.access$500(PoolDataSourceImpl.java:206), oracle.ucp.jdbc.PoolDataSourceImpl$31.build(PoolDataSourceImpl.java:4368), oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:1969), oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:1932), oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:1917), org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:126), org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:46), org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:126), org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:156), org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:164), org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:421), ... ]
疑问与分析
根据Oracle UCP官方对stale连接的处理指南,maxConnectionReuseTime正是针对池与数据库间存在防火墙、且防火墙会按时间阻断连接这类场景的配置,其作用是将池中存在时间超过设定值的连接关闭并移除,避免因防火墙阻断导致的无效连接留存。
当前配置中maxConnectionReuseTime设为1800秒(30分钟),小于防火墙超时的3600秒,但实际未观察到该配置生效:既没有连接因达到重用时间被关闭移除,日志中也无相关记录;闲置后池中的2个最小连接仍全部变为stale状态。
是否存在对该配置的理解错误或配置疏漏?怀疑maxConnectionReuseTime对满足minPoolSize设置的连接无效?
已知可以将minPoolSize设为0解决问题,但希望先明确maxConnectionReuseTime的预期行为,或找到其他可行的配置方案。
内容的提问来源于stack exchange,提问作者Jan Bentzen
相关产品推荐
相关产品推荐

