关于数据库连接池

阿宝洁猪 2017-06-08 10:14:19
项目中使用的是阿里的druid连接池,前段时间遇到一个问题

[DEBUG] 2017-06-06 02:01:09.044 [Druid-ConnectionPool-Destroy-1939995956] c.a.druid.pool.PreparedStatementPool - {conn-10001, pstmt-20152} exit cache
[DEBUG] 2017-06-06 02:01:09.044 [Druid-ConnectionPool-Destroy-1939995956] c.a.druid.pool.PreparedStatementPool - {conn-10001, pstmt-20172} enter cache
[ERROR] 2017-06-06 02:01:09.044 [Druid-ConnectionPool-Destroy-1939995956] c.alibaba.druid.pool.DruidDataSource - abandon connection, open stackTrace
at java.lang.Thread.getStackTrace(Thread.java:1589)
at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:995)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4544)
at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:661)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4540)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:919)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:911)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:98)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)

大部分人说是连接池超时,被强制回收。当时的配置是:
<!-- 超过时间限制是否回收 -->  
<property name="removeAbandoned" value="true" />
<!-- 超时时间;单位为秒。1800秒=30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />

我这定义的30分钟,什么情况下可以这么长时间一直占着连接呢?
我那个方法执行的时间确实比较长,是一个定时任务来着,大约40分钟左右才执行完(里面业务很复杂,有很多的crud操作),以前我的理解是每次对数据库的操作从连接池中拿一个连接,用完再放回连接池。所以不可能出现30分钟还没用完的情况。但是现在看来这个连接好像指的是整个方法所用的时间(第一个数据库操作完连接并没有放回连接池,第二个数据库操作的时候用的还是这个数据库连接)。才会导致最后超时。
为了验证这个连接指的是整个方法所用的时间,我把配置改成1小时,
<property name="removeAbandonedTimeout" value="36000" />  

结果发现这个问题不存在了,后来我延长了方法的执行时间,让方法1个多小时才能执行完,发现又报这个错,于是我把配置改成
<property name="removeAbandonedTimeout" value="100000" />  

错误又没有了。不知道我的理解对不对,或者谁有更好的解释,大家一起探讨下。
...全文
287 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
晨曦遇晓 2017-06-09
  • 打赏
  • 举报
回复
引用 3 楼 xiaojiezhu52100 的回复:
[quote=引用 2 楼 u014508939 的回复:] 我的理解是一个连接池里有若干条连接数据库的线程,至于线程池连接数据库的时间由你的配置文件决定,就如你所说的,你的那个方法因为连接到了数据库,而时间超过了你给定的时间,所以就报了异常,话说很少有执行需要那么长时间的方法,你那个方法如果一个人访问是30分钟,那2个同时访问,3个人,或者更多呢,不是很容易就出现问题嘛,所以就如你所说的,连接池的时间>执行连接数据库方法的时间,就没问题
那个方法里面不止一个操作,很多数据库操作的,难道是这个方法的所有数据库操作加起来总时长不能超过那个时间?[/quote] 对 是的 ,就好像你连接这个数据的方法是10分钟,而你设置线程池的最大连接时间是5分钟,也就是说你的一次连接数据库的最大时间不能超过5分钟,超过了就会自己断开
阿宝洁猪 2017-06-08
  • 打赏
  • 举报
回复
引用 2 楼 u014508939 的回复:
我的理解是一个连接池里有若干条连接数据库的线程,至于线程池连接数据库的时间由你的配置文件决定,就如你所说的,你的那个方法因为连接到了数据库,而时间超过了你给定的时间,所以就报了异常,话说很少有执行需要那么长时间的方法,你那个方法如果一个人访问是30分钟,那2个同时访问,3个人,或者更多呢,不是很容易就出现问题嘛,所以就如你所说的,连接池的时间>执行连接数据库方法的时间,就没问题
那个方法里面不止一个操作,很多数据库操作的,难道是这个方法的所有数据库操作加起来总时长不能超过那个时间?
晨曦遇晓 2017-06-08
  • 打赏
  • 举报
回复
我的理解是一个连接池里有若干条连接数据库的线程,至于线程池连接数据库的时间由你的配置文件决定,就如你所说的,你的那个方法因为连接到了数据库,而时间超过了你给定的时间,所以就报了异常,话说很少有执行需要那么长时间的方法,你那个方法如果一个人访问是30分钟,那2个同时访问,3个人,或者更多呢,不是很容易就出现问题嘛,所以就如你所说的,连接池的时间>执行连接数据库方法的时间,就没问题
Cx_轩 2017-06-08
  • 打赏
  • 举报
回复
时间调小了造成的

67,513

社区成员

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

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