removeAbandonedTimeout配置项的疑问

qq_25337487 2018-03-21 08:59:31
最近遇到一个【abandon connection】的异常,于是研究了下removeAbandonedTimeout这个配置项。
由于事先了解,removeAbandonedTimeout主要是用于回收连接池取出来使用,用完没有关闭的连接,超过配置的时间,就会回收,并抛出异常;所以先写了个测试类来验证。
用的DruidDataSource的连接池
连接池配置

<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="#{config.getValue('dataSource.url')}" />
<property name="username" value="#{config.getValue('dataSource.username')}" />
<property name="password" value="#{config.getValue('dataSource.password')}" />
<property name="driverClassName" value="#{config.getValue('dataSource.driverClassName')}" />
<property name="validationQuery" value="#{config.getValue('dataSource.validationQuery')}"></property>


<property name="initialSize" value="1" />
<property name="maxActive" value="3" />
<property name="minIdle" value="1" />
<property name="maxIdle" value="3" />
<property name="maxWait" value="100000" />

<property name="removeAbandoned" value="true"></property>
<property name="testOnBorrow" value="true"></property>
<property name="removeAbandonedTimeout" value="3"></property>
<property name="logAbandoned" value="true"></property>

<property name="poolPreparedStatements" value="false"></property>

<property name="testWhileIdle" value="true"></property>
<property name="testOnReturn" value="false"></property>
<property name="exceptionSorter">
<bean class="com.alibaba.druid.pool.vendor.MySqlExceptionSorter"></bean>
</property>

<property name="filters" value="stat" />
<property name="connectionProperties" value="druid.stat.slowSqlMillis=100" />
</bean>


测试类:

@Test
public void testAbd2() throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
try {
c1 = druidDataSource.getConnection();
c1.setAutoCommit(false);
c2 = druidDataSource.getConnection();
c2.setAutoCommit(false);
System.out.println("创建时间:" + new Date(System.currentTimeMillis()));

c1.commit();
c2.commit();

} catch (Exception e) {
e.printStackTrace();
}
}
}).start();

while(true){
System.out.println(new Date(System.currentTimeMillis()));
System.out.println(c1);
System.out.println(c2);
System.out.println("MaxActive:" + druidDataSource.getMaxActive());
System.out.println("ActiveCount:" + druidDataSource.getActiveCount());
Thread.sleep(10000);
}
}


但是执行后大概会在取得连接后40s左右才抛出异常,很奇怪,我明明配置的removeAbandonedTimeout是3秒啊。。

...全文
3964 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
博风 2019-07-19
  • 打赏
  • 举报
回复
默认当可用连接少于3个的时候开始扫描,扫描的时候才去计算他是否超过了你设置的timeout。超过了,就去除,没超过,就保留。
zslin2011 2018-11-15
  • 打赏
  • 举报
回复
我们知道,在Java中,即使设置了对象的finalize方法,我们也无法确切知道java垃圾回收线程会何时回收、何时调用对象的finalize方法,也就是说,Java垃圾回收机制会在“适当”的时机进行垃圾回收。
Druid数据库连接池,也有一个“连接回收线程”。设置removeAbandonedTimeout,只是表明,当连接回收线程扫描到这个连接时,要不要回收(连接超过removeAbandonedTimeout时间就回收),但是“连接回收线程”并不是实时对这个连接进行扫描。40s后,才扫描到这个连接,并发现这个连接已经大于removeAbandonedTimeout,那就40s后才抛出异常
qq_25337487 2018-03-23
  • 打赏
  • 举报
回复
引用 1 楼 tianfang 的回复:
1 可能是连接池初始化阶段,计时没有开始,可以先初始化连接池,等几十秒后再测试超时。 2 可能超时设置有最小值30-40s
感谢回答,我也觉得很可能是这个原因。但是真正验证可能还得把druid源码看一下了。
tianfang 2018-03-23
  • 打赏
  • 举报
回复
1 可能是连接池初始化阶段,计时没有开始,可以先初始化连接池,等几十秒后再测试超时。 2 可能超时设置有最小值30-40s

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧