Tomcat 连接池问题 - 无法在关闭的连接上调用方法

Posted

技术标签:

【中文标题】Tomcat 连接池问题 - 无法在关闭的连接上调用方法【英文标题】:Tomcat connection pool issue- Cannot call a method on closed connection 【发布时间】:2021-02-24 14:55:02 【问题描述】:

我的应用程序使用 Spring 2.5.x 并部署在 Tomcat 服务器上。有时,当我的数据库连接空闲时,我会收到以下错误:

[TeraJDBC 14.00.00.13] [错误 1095] [SQLState HY000] 无法调用 关闭连接的方法

这里是数据源配置

<bean id="dataSource"   class="org.apache.tomcat.jdbc.pool.DataSource"
          destroy-method="close">
    <property name="driverClassName" value="com.teradata.jdbc.TeraDriver"/>
    <property name="url" >
        <util:constant static-field="_DB_HOST"/>
    </property>
    <property name="username">
        <util:constant static-field="_DB_USER"/>
    </property>
    <property name="password">
        <util:constant static-field="_DB_PWD"/>
    </property>
    <property name="initialSize" value="1" />
    <property name="maxActive" value="50" />
</bean>

这里有没有我遗漏的配置?

【问题讨论】:

您能否在代码中展示如何获得连接并关闭连接? @stdunbar 我正在使用 spring jdbcTemplate 来调用存储过程,我假设 spring 负责关闭连接。 池可能正在返回一个关闭的连接(出于某种原因)。如果您没有连接有效的additional check,您可能会遇到您遇到的错误。 这能回答你的问题吗? Cannot call a method on closed connection, facing this issue after ideal time of connection tera data pool @PiotrP.Karwasz ,不,我正在寻找弹簧级解决方案 【参考方案1】:

虽然 Spring 的 JdbcTemplate 使用的所有连接在每个事务结束时都会关闭,但 Tomcat 的 JDBC Connection Pool 从未真正返回驱动程序获得的真实 ConnectionDataSource#getConnection 总是返回一个代理,这样Connection#close 会返回到池的连接而不是物理关闭它。

因此,如this answer 中所述,连接可能已被服务器关闭。因此,您需要配置池以验证连接,如answer cited by Kayaman。

我怀疑你的问题不是由连接问题引起的,而是服务器策略引起的,所以我会设置:

<property name="validationQuery" value="SELECT 66353343" /> 
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />

为了每 60 秒检查一次物理连接是否正常。

【讨论】:

每 60 秒检查一次不会增加数据库的额外负载,对 prod 环境来说这是一种好习惯吗? 每 60 秒几毫秒的工作几乎不会产生任何负载,它会让您的连接保持活跃。您也可以在从池中借用时进行测试,但这会稍微增加负载。

以上是关于Tomcat 连接池问题 - 无法在关闭的连接上调用方法的主要内容,如果未能解决你的问题,请参考以下文章

如何记录 Tomcat 7 JDBC 连接池、连接创建

如何关闭 clojure ring web 应用程序中的 Hikari 连接池部署到 elasticbeanstalk 中的 tomcat

DBCP,C3P0与Tomcat jdbc pool 连接池的比较

试图识别tomcat中废弃连接的来源

Tomcat连接池使用

取消部署war文件后关闭数据库池连接