getSessionFactory().openSession()导致druid连接池中的连接都占用满但无法回收
该问题产生的现象
页面刷新几次后,就卡住,线上就得需要重新部署(还好是测试环境,不是真正生产环境)
过程及原因
- 查看日志线程池满了
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60010, active 20, maxActive 20
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:280)
... 64 more
Caused by: com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60010, active 20, maxActive 20
at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1071)
at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:898)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4544)
- 原因
Mybatis中有一种不用写mapper和mapper.xml也可以和数据库连接的方法:通过使用sqlSession
执行拼接好的sql,直接运行,在创建连接时候(继承SqlSessionDaoSupport
)获取sqlMapper
,使用了getSessionFactory().openSession()
,配置中使用druid
连接池,导致一个现象就是,用到这个sqlMapper
的页面,只要刷新个几次就卡住了,导致每次不得不重启系统,如果是线上就得次次重新部署。
解决过程及办法
- 一开始先尝试,增加了druid的回收机制配置(properties配置文件,改为yml同理)
#druid recycle Druid的连接回收机制
#超过时间限制是否回收
spring.datasource.druid.removeAbandoned = true
#超时时间;单位为秒。180秒=3分钟
spring.datasource.druid.removeAbandonedTimeout = 180
#关闭abanded连接时输出错误日志
spring.datasource.druid.logAbandoned = true
通过这种办法,卡住了过一会再刷新就好了(也是概率问题,有的时候也会卡着),但这样也影响使用,未从根本解决问题
- 通过线程池总是达到最大值,判断是否是druid未回收之前的连接
经过debug,反复测试:原来是getSessionFactory().openSession()
的锅,所以改为了SqlSessionDaoSupport.getSqlSession()
这个方法,再通过SqlMapper sqlMapper = new SqlMapper(getSqlSession())
获取sqlMapper得以解决问题。
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » getSessionFactory().openSession()导致druid连接池中的连接都占用满但无法回收
自学咖网 » getSessionFactory().openSession()导致druid连接池中的连接都占用满但无法回收