近做一个定时任务类型的项目,此项目对数据库的访问间隔较长。这样就会导致测试的时候好好的,投入生产之后问题出现了。查看日志,原来是数据库连接池超时。网上看了一些解决方案,但是有些都不能解决问题。比较了几篇,经过自己实践成功后,将自己的连接池配置在这里分享下。
其他参数就不多说了,针对连接池失效的几个重要参数做下说明。
1、testOnReturn,testOnBorrow这两个参数为true,表示会在每次请求之前和之后进行连接池测试,如果连接失效,就会将这条连接对象销毁,创建一个新的连接对象,但是本次数据库操作也就失败了。对于读操作可能没什么问题,再请求一次就行了,但对于充值、定时任务等重要写操作来说还不够完美。(PS:使用这两个参数,一定要配置validationQuery参数,这样才会生效。)
2、为了解决以上问题,保证每次操作都有正常的连接池使用,我们来了解一下testWhileIdle参数。这个参数为true时候,表示空闲时是进行验证,检查对象是否有效。然后minEvictableIdleTimeMillis配合timeBetweenEvictionRunsMillis,每过timeBetweenEvictionRunsMillis秒对连接池进行一次检测,将对象闲置时间超过minEvictableIdleTimeMillis秒的对象进行销毁,创建新的对象来取代。这样就能保证时刻都有正常的连接池对象存在。
<bean id="readDS" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${slave.jdbc.driverClassName}"/>
<property name="url" value="${slave.jdbc.url}"/>
<property name="username" value="${slave.jdbc.username}"/>
<property name="password" value="${slave.jdbc.password}"/>
<property name="maxActive" value="300" />
<property name="maxIdle" value="50" />
<property name="minIdle" value="5" />
<property name="maxWait" value="30000" />
<property name="validationQuery" value="select current_date()" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="90" />
<property name="logAbandoned" value="false" />
<property name= "timeBetweenEvictionRunsMillis" value="30000" />
<property name= "numTestsPerEvictionRun" value="30" />
<property name="minEvictableIdleTimeMillis" value="1800000" />
</bean>