1:前言

最近在项目中使用多线程对大任务拆分处理时,进行数据库操作的时候报错了。

业务代码大概是这样的:

@Service
public calss TestServiceImpl implements TestService{
@Resource
private TestMapper testMapper; public void insert(Test test){
ThreadPoolExecutor executor = new ThreadPoolExecutor(...); executor.execute(() -> {
testMapper.insert(test);
});
} }

测试用例代码:

@RunWith(SpirngRunner.class)
@SpringBootTest
public class ApplicationTests{ @Resource
private TestService testService; @Test
public void insertTest(){
Test test = new Test();
testService.insert(test);
} }

2:排查思路

1:项目中使用了一个很老旧的定时器工具(LTS),由于配置未接入,启动时LTS一直会报错的,

我首先怀疑是LTS的问题,是不是内部某部分源码调用了DruidDataSource的close方法。

因此我在项目中先把LTS排除不让它启动。

结果:然并卵

2:后来怀疑是不是项目中的定时任务造成的,因为数据源关闭前打印了以下日志

可以看到 Thread-2 执行了ThreadPoolTaskExecutor 再关闭数据源的。

因此我在SpringBoot 的启动类上加上了以下代码

@SpringBootApplication(exclude = {TaskExecutionAutoConfiguration.class})

结果:然并卵

3:关电脑回家吃饭睡觉

第二天早上回到工位上缓了一会,思考还有什么原因会导致这种问题。

因为我们的线程池是一个封装的工具类封装过的(我封装的),里面有两行代码引起了我的注意:

我先把 threadPoolExecutor.awaitTermination(3, TimeUnit.MINUTES); 这行代码注释掉,重新跑测试用例。

发现并没有报错,并且程序很快就终止运行了。

在这里我就想到了,SpringBoot Test 中主线程退出,是不会管用户线程是否结束了任务的这个问题。

3:根本原因

1:SpringBoot Test 主线程退出,导致Spring 容器关闭。

2:Spring容器关闭,导致DruidDataSource 关闭

3:此时用户线程去访问已关闭的数据源,导致报错。

这样不行啊,那我测试用例怎么跑完呢?

可能这个时候有人会想到在测试用例最后面加以下代码:

TimeUnit.SECONDS.sleep(30);

可是本人觉得不够优雅,也不灵活。

4:解决方案

监听容器关闭,关闭前先判断线程池中是否存在未执行玩任务的线程。

ThreadPoolExecutor 的源码:



因此我们是可以知道是否存在未执行完任务的线程的。

所以我在项目中写了以下代码:

当线程池中存在未执行完任务的线程的时候,就先等待,直到所有任务完成或超过等待时间。

可把自己牛逼坏了(叉会腰)!

SpringBoot Test 多线程报错:dataSource already closed的更多相关文章

  1. springboot项目启动报错Failed to configure a DataSource: 'url' attribute is not specified and no embedde

    springboot项目启动报错Failed to configure a DataSource: 'url' attribute is not specified and no embedde 创建 ...

  2. Springboot数据库连接池报错的解决办法

    Springboot数据库连接池报错的解决办法 这个异常通常在Linux服务器上会发生,原因是Linux系统会主动断开一个长时间没有通信的连接 那么我们的问题就是:数据库连接池长时间处于间歇状态,导致 ...

  3. Springboot 之 启动报错-Cannot determine embedded database driver class for database type NONE

    Springboot 之 启动报错-数据库 springboot项目在启动时,报如下错误: Error starting ApplicationContext. To display the auto ...

  4. Springboot 启动文件报错,原因是@ComponentScan写成了@ComponentScans

    Springboot 启动文件报错,原因是@ComponentScan写成了@ComponentScans

  5. 【centOS】【xshell】xshell连接虚拟机上的centOS,操作途中突然断开连接,报错:connect closed by foreign host

    如题  xshell连接虚拟机上的centOS,操作途中突然断开连接,报错:connect closed by foreign host 快捷解决方法: 在虚拟机上centOS重新启动网络,即可解决问 ...

  6. springboot测试启动报错java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test

    springboot测试启动报错: java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you ne ...

  7. Springboot整合Elasticsearch报错availableProcessors is already set to [4], rejecting [4]

    Springboot整合Elasticsearch报错 今天使用SpringBoot整合Elasticsearch时候,相关的配置完成后,启动项目就报错了. nested exception is j ...

  8. SpringBoot集成MybatisPlus报错

    SpringBoot集成MybatisPlus报错 启动的时候总是报如下错误: java.lang.annotation.AnnotationFormatError: Invalid default: ...

  9. springboot项目启动报错 url' attribute is not specified and no embedded datasource could be configured

    报错相关信息: 2019-07-22 17:12:48.971 ERROR 8312 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : **** ...

随机推荐

  1. jdk 安装过程配置环境变量 error 的解决过程

    jdk 安装过程配置环境变量 error 的解决过程 问题背景: 我在安装 jdk 过程中在JAVA_HOME和path中添加路径后, cmd 中输入java 和javac均出现错误,因为之前在 D ...

  2. Codeforces Global Round 7 D1. Prefix-Suffix Palindrome (Easy version)(字符串)

    题意: 取一字符串不相交的前缀和后缀(可为空)构成最长回文串. 思路: 先从两边取对称的前后缀,之后再取余下字符串较长的回文前缀或后缀. #include <bits/stdc++.h> ...

  3. 2019HDU多校 Round10

    Solved:3 Rank:214 08 Coin 题意:n组硬币 每组有两个 分别有自己的价值 每组的第一个被拿了之后才能拿第二个 问拿1,2....2n个硬币的最大价值 题解:之前贪心带反悔的做法 ...

  4. Who Gets the Most Candies?

    Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 11303   Accepted: 3520 Case Time Limit ...

  5. 通过修改etcd来设置或修改节点flannel子网信息

    在首次启动flannel服务的时候可以手动指定subnet.env文件,配置所在节点的flannel子网网段,如果不指定配置文件,flannel将自动分配一个子网网段并生成配置文件 /var/run/ ...

  6. next v5升级到next v7需要注意的地方

    title: next v5升级到next v7需要注意的地方 date: 2020-03-04 categories: web tags: [hexo,next] 大部分的设置都是一样的,但有一些细 ...

  7. map最最最基本用法

    map<a,b>c中,a,b是变量类型 参数定义的map的名字 #include<stdio.h> #include<map> //头文件 map<int,c ...

  8. 洛谷p2216 多次单调队列,扫描矩阵中的最大值减去最小值最的固定大小子矩阵

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; int ...

  9. SPN在域环境中的应用

    0X01 SPN    服务主体名称(SPN)是Kerberos客户端用于唯一标识给特定Kerberos目标计算机的服务实例名称.Kerberos身份验证使用SPN将服务实例与服务登录帐户相关联.如果 ...

  10. 蓝湖 UI 设计稿上如何生成渐变色和复制渐变色

    蓝湖 UI 设计稿上如何生成渐变色和复制渐变色 Sketch 生成渐变色 不要上传图片,切图 如果是切图,切图模式下就不会生成 css 代码了 复制渐变色 OK .button { width: 28 ...