当前位置: 首页 > 知识库问答 >
问题:

Spring或hibernate连接泄漏

越麒
2023-03-14

我在webapp(hibernate-core-4.3.8。Final和Spring 3.2.11。RELEASE)上使用Spring和hibernate。我使用hikaricp(v 2.2.5)作为连接池impl,它检测连接泄漏并打印下面的stacktrac。我使用Spring的声明性事务划分,因此我假设资源的管理和清理是由Spring/hibernate完成的。因此,我认为Spring或hibernate是检测到的连接泄漏的原因。

基本上,有一个计时器,它在启动时调用一个标有@Transactional注释的Springbean。

 @Transactional public class InvoiceCycleExporter {
public runExportInvoiceCycleJob(){
  //this method when called is **sometimes** leaking a connection ....
} }

你能帮我追踪连接泄漏的来源吗?

我的appcontext。数据源、连接池和entitymanager的xml配置如下

 <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="maximumPoolSize" value="${jdbc.maximumPoolSize}"/>
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="leakDetectionThreshold" value="${jdbc.leakDetectionThreshold}"/>
</bean>

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="shutdown">
    <constructor-arg ref="hikariConfig"/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">        
    <property name="dataSource" ref="dataSource"/>
    <property name="persistenceUnitName" value="velosPU"/>
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>       //more stuff ....   
 </bean>

stacktrace如下:

2015-01-13 14:25:00.123 [Hikari Housekeeping Timer (pool HikariPool-0)] WARN  com.zaxxer.hikari.util.LeakTask - Connection leak detection triggered, stack trace follows
java.lang.Exception: null
        at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
        at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
        at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:70) ~[spring-orm-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:61) ~[spring-orm-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:378) ~[spring-orm-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372) ~[spring-tx-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417) ~[spring-tx-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255) ~[spring-tx-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) ~[spring-tx-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:633) ~[spring-aop-3.2.11.RELEASE.jar:3.2.11.RELEASE]
        at com.ukfuels.velos.services.bl.internalinterface.impl.bl.invoicing.**InvoiceCycleExporter (this is the spring bean marked with the transactional annotation)**$$EnhancerBySpringCGLIB$$519c078f.runExportInvoiceCycleJob(<generated>) ~[spring-core-3.2.11.RELEASE.jar:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_65]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_65]
        at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:67) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.impl.ProcessorEndpoint.onExchange(ProcessorEndpoint.java:103) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.impl.ProcessorEndpoint$1.process(ProcessorEndpoint.java:71) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:122) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:298) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:117) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.interceptor.BacklogTracerInterceptor.process(BacklogTracerInterceptor.java:84) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:91) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:391) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:273) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:46) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.interceptor.DefaultChannel.process(DefaultChannel.java:335) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:46) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.UnitOfWorkProcessor.processAsync(UnitOfWorkProcessor.java:150) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:117) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.RouteInflightRepositoryProcessor.processNext(RouteInflightRepositoryProcessor.java:48) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.loadbalancer.QueueLoadBalancer.process(QueueLoadBalancer.java:44) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:99) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.processor.loadbalancer.QueueLoadBalancer.process(QueueLoadBalancer.java:71) ~[camel-core-2.11.4.jar:2.11.4]
        at org.apache.camel.component.quartz.QuartzEndpoint.onJobExecute(QuartzEndpoint.java:113) ~[camel-quartz-2.11.4.jar:2.11.4]
        at org.apache.camel.component.quartz.CamelJob.execute(CamelJob.java:61) ~[camel-quartz-2.11.4.jar:2.11.4]
        at org.quartz.core.JobRunShell.run(JobRunShell.java:223) ~[quartz-1.8.6.jar:na]
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) ~[quartz-1.8.6.jar:na] **(a timer is triggered)**

共有2个答案

方奕
2023-03-14

这里主要讨论了这个问题:

https://github.com/brettwooldridge/HikariCP/issues/34

要缩小问题范围:

  1. 使用Hibernate 4尝试Spring 4
  2. 尝试其他数据源以查看问题是否仍然存在
锺离浩慨
2023-03-14

这里是一些信息,我认为可能是有用的调试连接泄漏一般

>

  • 排除假警报。例如,如果您有一个可能运行5分钟的事务(例如,在生成大型报告时),并且您已将“leakDetectionThreshold”参数(或所选池实现的等效参数)设置为4分钟,然后,任何耗时超过4分钟的事务都将被报告为泄漏,即使它可能不是真正的泄漏(事务可以在5分钟后正常完成并充分释放所有连接)
  • 如果您正在使用连接池,但偶尔会发现连接不足,请考虑如何配置连接池。在我的例子中,我将池配置为“maximumPoolSize”=100。Hikari将自动默认“minimumIdle”配置(HikariCP尝试在池中维护的最小空闲连接数)与“maximumPoolSize”的配置相同,因此启动时池将使用所有最大100个连接进行初始化。但这意味着,当“maxLifetime”(池中连接的最大生存期)启动时,所有连接都必须同时更新。这导致可用连接的临时急剧减少。在我的日志中,我偶尔会看到以下几行。

    HikariPool-0(总计=100,因努斯=0,可用=100,等待=0)
    HikariPool-0(总计=4,因努斯=0,可用=4,等待=0)
    HikariPool-0(总计=100,因努斯=0,可用=100,等待=0)

    第二行中,可用连接数下降到只有4个,这是在达到“maxLifetime”且连接需要更新时。因此,在配置池时,请确保连接在不同的时间过期。在我的例子中,我只是简单地将“minimumIdle”更改为40,这意味着随着服务器上负载的增加,将以增量方式获取新的连接(看看您的pool impl是否提供了与minToAcquire属性等效的连接),因此这些连接将具有不同的到期日期。

    您的连接“maxLifetime”需要小于数据库为连接分配/期望的值,以便不会在池中出现无效的连接。更新:某些数据库可能会在一段时间后强制断开连接。例如,postgres有“connectionTimeout”和“SockettTimeout”选项。因此,在应用程序的连接池中,您不希望保持连接的时间超过此db强制连接超时的时间,因为否则您将保持无效/已断开的连接。

  •  类似资料:
    • 在configuration类中: 在中: 这个效果不错。但我的问题是,在每一个请求之后,我会得到越来越多的空闲进程,并且在许多请求之后,我最终会得到以下结果: 这些明显泄漏的原因是什么? 为了完整起见,这里的一些示例在中使用:

    • 是否可以在2.3.9版本中启用泄漏检测?正如我之前在这个问题中所说,HiberNate使用的是HikariCP的2.3.3版本。截至2016年2月,他们已经升级了HikariCP的版本,但不幸的是升级到了2.3.9版本 我需要启用泄漏检测才能修复它们。我已将以下行添加到Hibernate配置文件中: 前两行运行正常,可以在调试日志中看到,但是当我添加第三行时,我无法运行应用程序。我也尝试过用代码添

    • 我在做java企业应用。该应用程序后端有hibernate框架。由于应用程序中最近的更改,一些代码消耗了weblogic server中的所有JDBC连接池。 应用程序连接是在代码中进行属性处理,对于每个线程,我们使用threadlocal类创建每个会话。所以创建连接没有问题。该应用程序已存在5年以上。 我们怀疑最近的代码更改会导致此主要问题。最后,我们决定使用探查器工具来调查此问题。 在此之前,

    • 我正在开发一个在Java服务器上运行的游戏。对于数据库池,我使用的是HikariCP,这是一个优秀的库,但它现在抛出了以下错误: 现在我知道连接泄漏意味着打开的连接在某个地方漂浮,但我不知道如何或在哪里漂浮。 下面是我的数据库类中的一个方法,根据堆栈跟踪,错误应该发生在这里。 这只是启动语句的一个基本方法。调用它时,我使用它,然后调用、和 但它告诉我连接是打开的。 我怎么解决这个?谢了!

    • 我在SpringBoot2中使用Hibernate5.3和Hikari2.7,通过官方的JDBC驱动程序使用FileMaker16数据源。 FileMaker服务器性能较差,SQL查询执行时间对于大表可以达到一分钟。有时,当连接池充满从未释放的活动连接时,它会导致连接泄漏。 问题是如何强制挂在池中的活动连接关闭,比如两分钟,将它们闲置并再次使用。 例如,我使用: 在raw中调用几次会导致连接泄漏,

    • 我已经在谷歌上搜索了4个多小时的stackoverflow来寻找我的问题的解决方案,阅读并试图了解正在发生的事情,但我没有遇到与我的问题相关的解决方案,所以抱歉,如果这听起来像是重复的,我会尽力解释到底发生了什么,这样我就可以深入了解C3P0的内部工作。 我有一个运行在Tomcat上的SpringMVC web应用程序,其中Hibernate、JPA和C3P0是我的池资源。重新加载页面时,应用程序