开发者社区> 问答> 正文

abandon connection, owner thread 和 connection hold

版本:1.0.22 使用Spring和Hibernate ,注解事务管理。 为了实验我把removeAbandonedTimeout 设为 30 。 30秒过后,就马上报了这个错误。 之后如果再进行操作任何操作,都是connection holder is null 配置

<!-- 配置数据源 -->
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      init-method="init" destroy-method="close">
    <property name="driverClassName" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>

    <!-- 初始化连接大小 -->
    <property name="initialSize" value="3"/>
    <!-- 连接池最大使用连接数量 -->
    <property name="maxActive" value="100"/>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="3"/>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWait" value="60000"/>

    <property name="validationQuery" value="${druid.validationQuery}"/>
    <property name="testOnBorrow" value="false"/>
    <property name="testOnReturn" value="false"/>
    <property name="testWhileIdle" value="true"/>

    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
    <property name="minEvictableIdleTimeMillis" value="300000"/>

    <!-- 打开removeAbandoned功能 -->
    <property name="removeAbandoned" value="true"/>
    <!-- 这边故意设置30秒,然后结果就是报错-->
    <property name="removeAbandonedTimeout" value="30"/>
    <!-- 关闭abanded连接时输出错误日志 -->
    <property name="logAbandoned" value="${druid.logAbandoned}"/>
    <!-- 监控数据库 -->
    <property name="filters" value="mergeStat" />

</bean>

异常

2016-07-15 21:01:54,727 [Druid-ConnectionPool-Destroy-505072145] ERROR [com.alibaba.druid.pool.DruidDataSource:2190] - abandon connection, owner thread: http-bio-8083-exec-9, connected at : 1468587675489, open stackTrace at java.lang.Thread.getStackTrace(Thread.java:1552) at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1071) at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4544) at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:662) at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4540) at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:995) at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:987) at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:103) at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139) at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380) at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228) at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:63) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:162) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:186) at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:160) at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1884) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1861) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838) at org.hibernate.loader.Loader.doQuery(Loader.java:909) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354) at org.hibernate.loader.Loader.doList(Loader.java:2553) at org.hibernate.loader.Loader.doList(Loader.java:2539) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369) at org.hibernate.loader.Loader.list(Loader.java:2364) at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:353) at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1873) at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:311) at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:141) at com.github.cnlinjie.infrastructure.dao.nativesql.NativeSqlDaoImpl.sqlListBeans(NativeSqlDaoImpl.java:206) at com.github.cnlinjie.infrastructure.dao.DaoImpl.sqlListBeans(DaoImpl.java:198) at pscode.dao.MakeLogDao.groupByAll(MakeLogDao.java:21) at pscode.service.MakeLogService.groupByAll(MakeLogService.java:35) at pscode.service.MakeLogService$$FastClassBySpringCGLIB$$a4bf1d16.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) at pscode.service.MakeLogService$$EnhancerBySpringCGLIB$$64af6406.groupByAll() at pscode.controller.MakeLogController.log(MakeLogController.java:36) at pscode.controller.MakeLogController$$FastClassBySpringCGLIB$$8384d37e.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:139) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) at pscode.controller.MakeLogController$$EnhancerBySpringCGLIB$$5b574df8.log() at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:168) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) ownerThread current state is WAITING, current stackTrace at sun.misc.Unsafe.park(Native Method) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104) at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

原提问者GitHub用户cnlinjie

展开
收起
山海行 2023-07-05 21:40:37 858 0
4 条回答
写回答
取消 提交回答
  • 北京阿里云ACE会长

    根据您提供的信息,可能是因为数据库连接超时导致连接被关闭,然后在之后的操作中使用已经关闭的连接导致出现“connection holder is null”的错误。

    在使用Spring和Hibernate进行注解事务管理时,可以通过配置数据源和事务管理器来管理数据库连接和事务。其中,数据源可以是基于连接池的,例如使用c3p0或HikariCP等连接池。在连接池中,可以设置removeAbandonedTimeout参数来指定连接被弃用的超时时间。如果连接被弃用的时间超过了这个时间,连接就会被关闭并从连接池中移除。

    如果在操作数据库时使用了已经被关闭的连接,就会出现“connection holder is null”的错误。这是因为连接已经被关闭,无法再进行任何操作。

    为了解决这个问题,可以尝试以下几个方法:

    增加数据库连接池中连接的数量,避免连接不足导致被关闭。

    将数据库连接池中的removeAbandonedTimeout参数设置为更大的值,避免连接被过早关闭。

    将事务管理器的隔离级别设置为更高的级别,例如SERIALIZABLE,避免出现并发冲突导致事务回滚的情况,从而减少连接被弃用的情况。

    在使用连接时,先检查连接是否可用,例如使用isValid方法进行检查,避免使用已经被关闭的连接。

    2023-07-30 09:39:18
    赞同 展开评论 打赏
  • 值得去的地方都没有捷径

    根据您提供的配置和异常信息,看起来您正在使用Druid连接池并遇到了一些问题。

    从异常信息中可以看到,连接所有者线程是"http-bio-8083-exec-9",连接创建时间是"1468587675489"。异常提示是"abandon connection",即连接被放弃了。这通常是由于连接长时间未被使用而被关闭,或者连接池配置中的"removeAbandonedTimeout"参数设置的时间太短引起的。

    根据您提供的配置,"removeAbandonedTimeout"参数被设置为30秒,这意味着如果一个连接在30秒内没有被使用,它将被判定为"abandoned"(被放弃的)。在您的场景中,30秒过后连接被放弃,但之后进行任何操作时都会出现"connection holder is null"的错误。这可能是由于连接已被关闭或清理而导致的。

    解决这个问题的一种方式是增加"removeAbandonedTimeout"的值,以适应您的应用场景。您可以根据实际情况调整这个值,确保连接在合理的时间内不被放弃。

    另外,您还可以检查一下其他连接池相关的配置参数是否正确设置,比如"maxActive"(最大活动连接数)和"minIdle"(最小空闲连接数)等,确保连接池能够满足应用程序的需求。

    如果问题仍然存在或需要进一步帮助,请提供更多的相关信息,以便我能够更准确地回答您的问题。

    2023-07-11 17:06:36
    赞同 展开评论 打赏
  • 抱歉,不是druid的问题。 找到问题了,用的那个数据访问框架用hql的时候是 

    this.sessionFactory.getCurrentSession();

    而用sql的时候,用:

    this.sessionFactory.openSession();

    这个需要自己手动关闭,没关闭就会一直连接。

    原回答者GitHub用户cnlinjie

    2023-07-06 12:16:39
    赞同 展开评论 打赏
  • 根据您提供的信息,您遇到了Druid连接池的一个异常。该异常是因为连接所有者线程已经放弃了对连接的控制权,但在销毁连接时仍然存在问题。

    这个问题可能是由于连接超时设置不正确引起的。根据您的配置,removeAbandonedTimeout被设置为30秒,这意味着如果一个连接在30秒内没有被使用,则会被认为是废弃的并且被移除。

    一种可能的原因是,连接在30秒后被放弃,并且连接池试图销毁它。但是,在销毁连接时出现了问题,导致抛出了异常。

    为了解决这个问题,您可以尝试以下几个步骤:

    1. 确保removeAbandonedTimeout的值设置正确。如果您希望连接在30秒内未使用时被认为是废弃的,请确保此值正确设置。

    2. 检查是否有其他配置或代码导致连接被放弃。例如,检查是否有其他地方手动关闭了连接,而没有将其返回到连接池中。

    3. 升级Druid连接池的版本。有时候问题可能是由连接池本身的一个bug引起的。更新到最新版本可能会修复这个问题。

    4. 如果以上步骤都没有解决问题,您可以尝试使用其他连接池来替代Druid连接池,以查看是否仍然存在相同的问题。

    2023-07-06 09:15:43
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载