testOnBorrow、testOnReturn、testWhileIdle,他们的意思是当是取得连接、返回连接或连接空闲时是否进行有效性验证(即是否还和数据库连通的),默认都为false。所以当数据库连接因为某种原因断掉后,再从连接池中取得的连接,实际上可能是无效的连接了,所以,为了确保取得的连接是有效的, 可以把把这些属性设为true。当进行校验时,需要另一个参数:validationQuery,对oracle来说,可以是:SELECT COUNT(*) FROM DUAL,实际上就是个简单的SQL语句,验证时,就是把这个SQL语句在数据库上跑一下而已,如果连接正常的,当然就有结果返回了。 在SQL2005上可以是:"SELECT 1 "就可以了。
还有2个参数:timeBetweenEvictionRunsMillis 和 minEvictableIdleTimeMillis, 他们两个配合,可以持续更新连接池中的连接对象,当timeBetweenEvictionRunsMillis 大于0时,每过timeBetweenEvictionRunsMillis 时间,就会启动一个线程,校验连接池中闲置时间超过minEvictableIdleTimeMillis的连接对象。
<bean id="mtc_dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${db.driverClassName}" />
<property name="url"
value="${db.url}:${db.port};DatabaseName=NIHAO" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="initialSize" value="5" />
<property name="maxActive" value="20" />
<property name="maxWait" value="-1" />
<property name="maxIdle" value="100" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="30000" />
<property name="logAbandoned" value="true" />
<property name="validationQuery" value="select 1 " />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="true"></property>
<property name="testWhileIdle" value="true"></property>
</bean>
异常信息 Hibernate Cannot release connection,添加上面红色标示的属性后解决问题。
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.close(ConnectionManager.java:318)
at org.hibernate.impl.SessionImpl.close(SessionImpl.java:298)
at com.nihao.queryDB(BasicAlarmDBDAO.java:31)
at com.nihao.queryRecordCount(CurrentAlarmDAO.java:158)
at com.nihao.Task.run(SynAlarmTask.java:30)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Caused by: java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:84)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:181)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.closeConnection(LocalDataSourceConnectionProvider.java:95)
at org.hibernate.jdbc.ConnectionManager.closeConnection(ConnectionManager.java:445)