使用c3p0连接池释放MySQL连接

时间:2019-08-27 17:47:57

标签: mysql hibernate c3p0

我们正在使用休眠和MySql。我们使用c3p0创建一个连接池。根据我的研究,我在persistence.xml文件中提供了以下这些设置。 据我了解,数据库连接数绝不能低于最小值10,并且连接寿命达到14400(4小时)时,它将关闭并重新连接。

<property name="hibernate.c3p0.min_size" value="10" />
<property name="hibernate.c3p0.max_size" value="100" />
<property name="hibernate.c3p0.acquire_increment" value="10" />
<property name="hibernate.c3p0.max_statements" value="1000" />
<property name="hibernate.c3p0.numHelperThreads" value="30" />
<property name="hibernate.c3p0.timeout" value="14400" />
<property name="hibernate.c3p0.maxIdleTimeExcessConnections" value="1800" />
<property name="hibernate.c3p0.validate" value="false" />
<property name="hibernate.c3p0.idle_test_period" value="3600" />
<property name="hibernate.c3p0.preferredTestQuery" value="select id from contact limit 1" />
<property name="hibernate.c3p0.acquireRetryAttempts" value="100" />
<property name="hibernate.c3p0.acquireRetryDelay" value="1000" />
<property name="hibernate.c3p0.breakAfterAcquireFailure" value="true" />

使用此查询,我监视连接。我看到连接数从ar 10开始,对于空闲连接,过程时间爬升到3600并根据idle_test_period重置。但是大约一天后,我再次检查它,发现连接数减少到9。到本周末,连接数减少到6。当连接数达到1时,程序将锁定而不会抛出尝试运行数据库查询时出现异常。

SELECT 
    performance_schema.threads.PROCESSLIST_ID,
    performance_schema.threads.PROCESSLIST_USER,
    performance_schema.threads.PROCESSLIST_HOST,
    performance_schema.threads.PROCESSLIST_TIME
FROM performance_schema.threads
WHERE performance_schema.threads.PROCESSLIST_USER = 'loginname'
ORDER BY performance_schema.threads.PROCESSLIST_HOST, performance_schema.threads.PROCESSLIST_TIME;

正如我说的,空闲连接的PROCESS_TIME上升到3600,但是昨天我看到一个上升到17000,然后第二天早上连接被关闭,我的连接数减少到5。

我这里缺少什么吗?开放的连接至少应保持10个吗?这些设置中有什么可以保持连接保持打开状态或保持状态吗?

1 个答案:

答案 0 :(得分:1)

您很有可能发生Connection泄漏,也就是说,有时您的应用程序无法在其签出的连接上调用close()

c3p0通常不会干扰已检出并在客户端控制下的连接。特别是,hibernate.c3p0.timeoutc3p0.maxIdleTime)将不会被强制执行,因此最终泄漏的连接将在mysql端超时,但从c3p0的角度来看,它将永远处于使用状态。最终,所有连接将被检出但已死,并且新客户端将无限期挂起(除非设置了c3p0.clientTimeout),以等待永远不会可用的连接。

您的帖子中唯一与此假设不符的地方是,您将hibernate.c3p0.max_sizec3p0.maxPoolSize)设置为100,因此当签出100个连接而不仅仅是10个时,冻结的是您,除非有一个服务器端限制正在执行。但是,由于您正在查看服务器端打开的连接,因此不清楚它们与客户端打开的连接之间的映射,因为您只会看到已打开但尚未超时的连接。但是,如果您看不到超过10个打开的连接,我仍然感到非常惊讶。

仍然,我要做的第一件事是调试或至少解决连接泄漏问题。 c3p0的“从不检查已退出连接”规则的主要例外是unreturnedConnectionTimeout,您可以将其配置为hibernate.c3p0.unreturnedConnectionTimeout。它将关闭已签出但在您定义的时间过长后仍未返回的连接。

但是,最好是消除连接泄漏,而不仅仅是解决它们。将设置为hibernate.c3p0.debugUnreturnedConnectionStackTraces的配置属性debugUnreturnedConnectionStackTraces设置为true的同时将unreturnedConnectionTimeout设置为Connection.close(),并且将生成将永远不会关闭的连接的堆栈跟踪打印到您的日志中。然后,您可以尝试了解导致某些连接打开但从未关闭的代码路径。通常,这与不使用对所有Exception-al情况都强健的{{1}}策略有关。在Java 7之后,try-with-resources构造对解决这个问题非常有帮助。