转载:http://hi.baidu.com/iloverobot/blog/item/22148e032dac63e008fa9391.html
Hibernate : Cannot release connection 错误的解决方法
2010年05月18日 星期二 15:48
问题:
系统采用Spring MVC 2.5 + Spring 2.5 + Hibernate 3.2架构,其中数据源连接池采用的是Apache commons DBCP。问题是这样的,系统运行一段时间后(大致每隔8小时),访问系统会出现如下错误,再次访问恢复正常。
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.exception.GenericJDBCException: Cannot release connection
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:583)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
Caused by: org.hibernate.exception.GenericJDBCException: Cannot release connection
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
at org.hibernate.jdbc.ConnectionManager.closeConnection(ConnectionManager.java:449)
at org.hibernate.jdbc.ConnectionManager.cleanup(ConnectionManager.java:379)
at org.hibernate.jdbc.ConnectionManager.manualDisconnect(ConnectionManager.java:333)
at org.hibernate.impl.SessionImpl.disconnect(SessionImpl.java:375)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCleanupAfterCompletion(HibernateTransactionManager.java:744)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:989)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:855)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:800)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:339)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:421)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:136)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:326)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:313)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
36 more
Caused by: java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:77)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:180)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.closeConnection(LocalDataSourceConnectionProvider.java:96)
at org.hibernate.jdbc.ConnectionManager.closeConnection(ConnectionManager.java:445)
62 more
解决:
造成Cannot release connection的原因有很多,要具体问题具体分析。从异常分析,造成这个异常 org.hibernate.exception.GenericJDBCException: Cannot release connection 归根结底是Caused by: java.sql.SQLException: Already closed. 即连接已关闭。所以解决的办法就要从DBCP的参数配置入手,见下面的参数配置properties文件。
#### :: Apache DBCP :: ####
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@10.165.153.9:1521:PRDC
jdbc.username=guser
jdbc.password=guser
#初始化连接
jdbc.initialSize=0
#连接池的最大活动个数
jdbc.maxActive=20
#没有人用连接的时候,最大闲置的连接个数。
jdbc.maxIdle=100
#没有人用连接的时候,最小闲置的连接个数。
jdbc.minIdle=0
#超时等待时间以毫秒为单位
jdbc.maxWait=10000
#是否自动回收超时连接
jdbc.removeAbandoned=true
#设置被遗弃的连接的超时的时间(以秒数为单位),即当一个连接被遗弃的时间超过设置的时间,则它会自动转换成可利用的连接。默认的超时时间是300秒。
jdbc.removeAbandonedTimeout=60
#是否在自动回收超时连接的时候打印连接的超时错误
jdbc.logAbandoned = true
#给出一条简单的sql语句进行验证
jdbc.validationQuery=select 1 from dual
#在取出连接时进行有效验证
jdbc.testOnBorrow=true
其中标红的两个参数的作用是对池化连接进行验证,This will ensure that DBCP only hands out good connections to Hibernate. 故加上这两个参数后,这个异常就不会再出现了。在Spring中指定数据源如下:
<!-- 數據源定義 使用Apache DBCP連接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="${jdbc.maxActive}" />
<property name="maxIdle" value="${jdbc.maxIdle}" />
<property name="maxWait" value="${jdbc.maxWait}" />
<property name="removeAbandoned" value="${jdbc.removeAbandoned}" />
<property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
<property name="logAbandoned" value="${jdbc.logAbandoned}" />
<property name="validationQuery" value="${jdbc.validationQuery}" />
<property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
</bean>
问题解决了。
另附
DBCP参数详细说明(部分参考了 http://justin-ray.javaeye.com/blog/413591 ):
在配置时,大部分参数一目了然,不再赘述,有不清楚的话,可以参考下面的详细说明。主要难以理解的参数主要有:removeAbandoned 、logAbandoned、removeAbandonedTimeout、maxWait这四个参数,设置了rmoveAbandoned=true那么在getNumActive()快要到getMaxActive()的时候,系统会进行无效的Connection的回收,回收的Connection为removeAbandonedTimeout(默认300秒)中设置的秒数后没有使用的Connection,激活回收机制大致为getNumActive()=getMaxActive()-3。logAbandoned=true的话,将会在回收事件后,在log中打印出回收Connection的错误信息,包括在哪个地方用了Connection却忘记关闭了,在调试的时候很有用。在这里个人建议maxWait的时间不要设得太长,maxWait如果设置太长那么客户端会等待很久才激发回收事件。
分享到:
相关推荐
Hibernate面试题专栏 - 最全的Hibernate面试题, Hibernate笔试题, Hibernate问题 Hibernate教程
Hibernate问题 <br>1、表连接的查询,当表中有外键连接其它表时,如何能一次查出所有的内容? 2、同样表连接查询,如何根据连接表的内容进行查询?同上例,如何根据rolename查询user中的信息? 3. ...
\Hibernate 问题集锦.docx
利用hibernate往数据库里插入数据时,不能插入集合,只能插入对象
Hibernate相关jar包括新版本jdk不兼容旧版本的jar.zip
spring+hibernate包冲突问题 spring+hibernate包冲突问题
本人做系统时遇到的一些Hibernate问题及解决方案。
hibernate_问题详解hibernate_问题详解hibernate_问题详解hibernate_问题详解hibernate_问题详解hibernate_问题详解hibernate_问题详解
Hibernate不得不注意的问题,以及Hibernate的数据源
SpringMVC_+_spring3.1.1_+_hibernate4.1.0_集成及常见问题总结
hibernate常见问题及处理。
Dwr+Hibernate的Lazy问题 解决了Hibernate延迟加载失效问题
Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板Hibernate留言板
解决hibernate监听器死循环问题
Hibernate封装了很多有用的API给开发者,降低了操作数据库的难度和复杂度,同时也减少了模板代码的数量,但Hibernate留给开发者可操作的空间相对Mybatis少了很多。 Mybatis框架使用起来很灵活,开发者可以自定义查询...
hibernate逆向生成小问题,主要是由数据库反向自成domain.
hibernate效率注意的几个问题,批量删除和批量更新建议用JDBC,这是一个原则,当然有的时候可能必须用Hibernate来批量更新和批量删除,那么这个时候我想说的就是,Hibernate批量更新和删除效率并非传说中的那么差,...
Hibernate案例与专题-缓存问题。详细了介绍了Hibernate的缓存机制
Hibernate 使用缓存时,数据同步问题
hibernate的中文问题的解决方案