使用线程池就报Could not get JDBC Connection 主线程就没问题

ackerHu 2020-06-24 11:20:24
### The error occurred while executing a query
###Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.DataSourceClosedException: dataSource already closed at Wed Jun 24 11:12:25 CST 2020

不使用线程池,使用主线程是OK的 ,使用线程池数据库就关闭了

下面的是数据库连接池的代码:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">

<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${platform.jdbc.url}" />
<property name="username" value="${platform.jdbc.username}" />
<property name="password" value="${platform.jdbc.password}" />
<property name="driverClassName" value="${platform.jdbc.driver}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${platform.druid.initialSize}" />
<property name="minIdle" value="${platform.druid.minIdle}" />
<property name="maxActive" value="${platform.druid.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${platform.druid.maxWait}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${platform.druid.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${platform.druid.minEvictableIdleTimeMillis}" />
<property name="validationQuery" value="${platform.druid.validationQuery}" />
<property name="testWhileIdle" value="${platform.druid.testWhileIdle}" />
<property name="testOnBorrow" value="${platform.druid.testOnBorrow}" />
<property name="testOnReturn" value="${platform.druid.testOnReturn}" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。 -->
<property name="poolPreparedStatements" value="${platform.druid.poolPreparedStatements}" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="${platform.druid.maxPoolPreparedStatementPerConnectionSize}" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="${platform.druid.filters}" />
</bean>

<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:config/mybatis-config.xml" />
<property name="mapperLocations" value="classpath:sqlmap/*Mapper.xml" />
</bean>
<!-- 配置事务管理器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- enable transaction annotation support -->
<tx:annotation-driven transaction-manager="txManager" />

<!-- 配置mybatis需要扫描的包 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.dshamc.qa.platform.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>
...全文
11994 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
hiboys 2020-07-21
  • 打赏
  • 举报
回复
看看你的连接池支持多线程吗?需要配置支持多线程不? 担心一个连接对象分配给2个线程。第一个线程用完连接关闭,第二个线程再使用就 already closed
冰思雨 2020-07-20
  • 打赏
  • 举报
回复
楼主还是没有找到问题的原因啊。 你看看你的代码里面,有没有把一个数据库事务,用多线程来处理了? 一个数据库事务,要唯一分配给同一个线程来处理才行。如果一个数据库事务由多个线程来完成的话,需要特殊(设置)处理才行。
ackerHu 2020-07-16
  • 打赏
  • 举报
回复
引用 7 楼 冰思雨 的回复:
综合来看,凭经验猜测,应该是我上面提到的情况2,长时间未使用连接,连接被数据库关闭了。
楼主要将 testWhileIdle 打开(设置成true),当连接闲置时进行心跳唤醒操作(就是向数据库发送一个SQL来激活连接,比如 SELECT 1 之类的),然后,把闲置超时的时间,设置的短一点,一般来讲,这个闲置超时,是数据库空闲连接超时时间的三分之二。



问题是代码块只要用到线程池去操作数据源就关闭了 不用线程池去处理就是OK的 现在问题已经解决了 用线程池处理代码的时候我是本地main跑的 我把代码放到tomcat上就可以了 谢谢大家
冰思雨 2020-07-01
  • 打赏
  • 举报
回复
综合来看,凭经验猜测,应该是我上面提到的情况2,长时间未使用连接,连接被数据库关闭了。 楼主要将 testWhileIdle 打开(设置成true),当连接闲置时进行心跳唤醒操作(就是向数据库发送一个SQL来激活连接,比如 SELECT 1 之类的),然后,把闲置超时的时间,设置的短一点,一般来讲,这个闲置超时,是数据库空闲连接超时时间的三分之二。
冰思雨 2020-07-01
  • 打赏
  • 举报
回复
现象描述的场景不够具体。 你是在什么场景下出现的问题? 比如: 1. 连续两次使用数据库连接,第一次正常,第二次报错? 2. 长时间不使用连接,一旦使用就报错? 3. 有一个业务函数,执行时间很长,当调用这个业务函数的时候,就会报错? 上述三种情况,是哪一种? 情况1,说明你从连接池里面拿到了被关闭的连接,尝试 testOnBorrow=true 看看能否解决问题。 情况2,说明上时间未使用的连接被数据库关闭了,尝试 testWhileIdle=true。 情况3,说明业务函数的设计有问题,尝试持有数据库连接却不使用,造成连接被数据库关闭。更改业务逻辑,要把业务函数中,关于数据库的操作集中在一起封装成函数,运行封装后的函数时从连接池中拿连接,运行完后交还连接。
ackerHu 2020-06-29
  • 打赏
  • 举报
回复
可以非常感谢
ackerHu 2020-06-24
  • 打赏
  • 举报
回复
我的是mysql
ackerHu 2020-06-24
  • 打赏
  • 举报
回复
哪位大佬能帮忙看一下 定位了1天了 没看出问题来 需要我提供信息的留言一下 我来提供
ptclin_2007 2020-06-24
  • 打赏
  • 举报
回复
加我的QQ? 105009010
ptclin_2007 2020-06-24
  • 打赏
  • 举报
回复
帮你远程协助看看?

81,122

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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