使用BasicDataSource引发的数据库连接中断的问题和解决方法

本文详细阐述了一个应用程序在首次系统访问时出现数据库连接超时错误的问题,通过分析发现是由于数据库连接池配置不当导致。文章深入探讨了DBCP配置中的关键参数,包括测试连接的有效性、检测执行时间长的连接、周期性连接检测的时间间隔等,并提供了详细的配置示例,旨在帮助开发者解决类似问题,确保系统的稳定性和性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近碰到一个问题,应用程序每天的第一次进行系统访问时,会报一个奇怪的错误,最后经过仔细的跟踪,错误信息找到了,如下所示:

1
The last packet successfully received from the server was 60,428,178 milliseconds ago.  The last packet sent successfully to the server was 60,428,180 milliseconds ago

很明显,这个错误信息表示数据库连接实际上已经断开了,因为在深夜没有客户来访问系统。但是程序中并没有检测到这个信息,仍然使用过期的数据库连接,那肯定会报错。而在之后,datasource检测到这个问题,则尝试重新进行连接,这样接下来的链接就正常了。
在项目中使用的数据库连接池是dbcp,即apache-dbcp的BasicDataSource。最初的配置为:

1
2
3
4
5
6
7
8
9
<bean id="dataSourceLog" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="" />
        <property name="defaultAutoCommit" value="" />
        <property name="url" value="" />
        <property name="username" value="" />
        <property name="password" value="" />
        <property name="maxActive" value=""/>
</bean>

经仔细分析,这样的配置不会对连接的连接超时以及有效性进行检测,因此会发生以上的问题。要解决这个问题,就需要额外的检测手段和处理方法,还好,dbcp本身提供了这些配置,只不过当前系统中并没有这样的配置。

在处理这个问题中,需要处理好以下这些问题

  • 连接多少时间的数据库连接被认为是无效的
  • 如何检测一个连接是有效的
  • 如何检测那些执行SQL时间长的连接
  • 周期性连接检测需要多长时间执行一次

上面的这些问题,dbcp都提供了有效的配置方法,只需要详细的配置即可。如详细的配置如下:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
//是否要进行检测
        <property name="testWhileIdle" value="true"/>
//进行检测一个连接是有效的SQL语句,比如oracle是select 1 from dual 而 mysql是 select 1
        <property name="validationQuery" value=""/>
//是否在数据库连接请求量大的时候,如总数50,当前已请求了49个,所剩不多了,检测那些执行时间久的连接,将其从池中移除掉(移除之后怎么作,由实现决定,如直接断开,或者任其继续执行等)
        <property name="removeAbandoned" value="true"/>
//一次数据库操作执行时间超过多少秒的连接被认为是需要移除的
        <property name="removeAbandonedTimeout" value=""/>
//每隔多少时间检测一次,比如每半小时检测一次,总不能总是检测,这会对性能产生影响
        <property name="timeBetweenEvictionRunsMillis" value=""/>
//每次检测时,需要检测多少个数据连接,一般设置为与最大连接数一样,这样就可以检测完所有的连接
        <property name="numTestsPerEvictionRun" value=""/>
//一个数据库连接连接多少时间之外,我们认为其应该不再适用了(可能下一次就会失效了),应该移除并重新建立连接了
        <property name="minEvictableIdleTimeMillis" value=""/>

经过这样配置之后,之前的问题就不再出现了。引起这个问题的原因是多方面的,但对于问题主因,仍是对dbcp未完全了解,总是按默认配置进行开发。在某些场景下就会突发一些想不到的问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值