Hibernate/c3p0 连接泄漏
Posted
技术标签:
【中文标题】Hibernate/c3p0 连接泄漏【英文标题】:Hibernate/c3p0 connection leak 【发布时间】:2011-02-18 06:38:51 【问题描述】:我们正在负载下运行 spring/hibernate/c3p0 应用程序。当我将 c3p0 maxPoolSize 减少到远低于并发用户数时,我们的应用程序就会挂起。日志中没有错误消息,但它也不会继续前进。
我预计应用程序会变慢,但不会完全停止。
这是我们的 c3p0 配置:
<bean id="coreDataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="$core.jdbc.driver"
p:jdbcUrl="$core.jdbc.url"
p:user="$core.jdbc.user"
p:acquireIncrement="5"
p:acquireRetryAttempts="10"
p:acquireRetryDelay="5000"
p:initialPoolSize="52"
p:maxIdleTime="3600"
p:maxIdleTimeExcessConnections="300"
p:minPoolSize="52"
p:maxPoolSize="125"
p:numHelperThreads="6"
p:unreturnedConnectionTimeout="0">
<property name="password">
<bean class="com.docfinity.util.encryption.SpringStringDecrypter"
p:decryptFlag="$core.jdbc.decryptPasswordFlag"
p:encryptedString="$core.jdbc.password" />
</property>
</bean>
如果我向它扔 160 个用户,它会被锁定。
我尝试将 unreturnedConnectionTimeout 设置为正值(120 秒),并查看了显示在我们的应用程序中的堆栈跟踪。堆栈跟踪来自我们应用程序中的各种不同方法。这并不是说我们可以指出一种方法并说它正在泄漏连接。
任何调试此问题的帮助将不胜感激。
【问题讨论】:
【参考方案1】:查询您的数据库:
select * from pg_stat_activity;
并检查哪些查询以idle in transaction
状态持续存在。尝试在您的代码中找到它们并研究交易未完成的原因。
在代码/配置中检查的几件事:
明确提交事务或使用@Transactional
。请注意,@Transactional
仅适用于公共方法。
如果您使用的是 Hibernate 5.1.0.Final,那么 persistence.xml 应该包含:
<property name="hibernate.connection.provider_class" value="org.hibernate.c3p0.internal.C3P0ConnectionProvider" />
代替:
<property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" />
<property name="hibernate.enable_lazy_load_no_trans" value="true" />
延迟加载时可能会导致连接泄漏。相关讨论:
org.hibernate.LazyInitializationException - could not initialize proxy - no Session Solve Hibernate Lazy-Init issue with hibernate.enable_lazy_load_no_trans查看相关文章:
The best way to detect database connection leaks How we fixed all database connection leaks【讨论】:
【参考方案2】:这篇文章描述了how to debug c3p0 connection leak issue 使用参数和堆栈跟踪。希望这会有所帮助
【讨论】:
【参考方案3】:Hibernate 和 Spring 不是泄漏连接的,您的应用程序中的某个地方正在泄漏。我不确定 C3P0 但 BoneCP (http://jolbox.com) 支持检测未关闭的连接(并为您提供打开它们的位置的堆栈跟踪)+ 当线程在没有适当清理的情况下死亡时,将为您关闭任何泄漏的连接。
【讨论】:
【参考方案4】:我怀疑 Hibernate 或 Spring 是否存在连接泄漏,我怀疑某处的配置问题导致您的应用程序运行我们的连接。这是我会做的:
降低并发用户数和池大小,我不确定问题是否与负载有关。
将unreturnedConnectionTimeout
设置为大于0
的值,并结合debugUnreturnedConnectionStackTraces
至true
确定连接在哪里被签出而不返回到池中,并发布一些生成的堆栈跟踪。
确定出现问题的一个业务流程(一个用例场景),并仅在发现问题之前在该场景上运行测试。
另外,我会用一两个堆栈跟踪更新问题,也许有人会发现一些明显的东西。
【讨论】:
以上是关于Hibernate/c3p0 连接泄漏的主要内容,如果未能解决你的问题,请参考以下文章
Postgresql + Hibernate3 + C3p0 = 不关闭连接
我可以使用 Spring/Hibernate/c3p0 为多个数据库使用一个池数据源吗?