ssm项目,如果启动后不使用过段时间再次访问会报数据库连接超时的错误,大致信息如下:
Could not close JDBC Connection java.sql.SQLException: Already closed.
Caused by: java.net.SocketTimeoutException: Read timed out
项目使用dbcp连接池,但因为时老项目,之前的同事只是在ApplicationContext.xml进行基本配置如下:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${driverClassName}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> <property name="url" value="${url}" /> </bean>
问题解决
修改配置参数
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${driverClassName}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> <property name="url" value="${url}" /> <!--initialSize: 初始化连接--> <property name="initialSize" value="5"/> <!--maxIdle: 最大空闲连接--> <property name="maxIdle" value="10"/> <!--minIdle: 最小空闲连接--> <property name="minIdle" value="5"/> <!--maxActive: 最大连接数量--> <property name="maxActive" value="15"/> <!--removeAbandoned: 是否自动回收超时连接--> <property name="removeAbandoned" value="true"/> <!--removeAbandonedTimeout: 超时时间(以秒数为单位)--> <property name="removeAbandonedTimeout" value="180"/> <!--maxWait: 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒--> <property name="maxWait" value="3000"/> <property name="validationQuery"> <value>SELECT 1</value> </property> <property name="testOnBorrow"> <value>true</value> </property> </bean>
主要说明:
- TestOnBorrow=false时,由于不检测池里连接的可用性,于是假如连接池中的连接被数据库关闭了,应用通过连接池getConnection时,都可能获取到这些不可用的连接,且这些连接如果不被其他线程回收的话,它们不会被连接池被废除,也不会重新被创建,占用了连接池的名额。
参考链接DBCP连接池TestOnBorrow的坑_seaboat——a free boat on the sea.(公众号:远洋号)-CSDN博客