批量插入导致数据库连接异常java.sql.SQLTransientConnectionException

1,背景:
这是一个解析Txt 保存更新内容接口

 /**
     * analysis txt,insert every line content but except first line
     */
    @PostMapping("txt")
    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "解析接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name="dispatchBid",dataType="Long",required=true,value="调度任务Bid",defaultValue="0"),
            @ApiImplicitParam(name="executionBid",dataType="Long",required=true,value="执行任务bid",defaultValue="0")
    })
    public InvokeResultUtil<Object> analysisTxt(@RequestBody MultipartFile multipartFile,
                                        @RequestParam("dispatchBid") Long dispatchBid,
                                        @RequestParam("executionBid") Long executionBid,
                                        @RequestParam("sourceType") Integer sourceType

    ) {
        try {
            log.info("analysisTxt 入参 MultipartFile:{},dispatchBid:{},executionBid:{},", multipartFile, dispatchBid, executionBid);
            if (multipartFile.isEmpty() || judgeFormat(arr, multipartFile)) {
                return InvokeResultUtil.failure(BizStatusCodeEnum.MISSING_PARAMS.getCode(), "上传文件为空或文件格式不匹配");
            }

            MsDispatchTask task = taskService.getMsDispatchTaskByBid(dispatchBid);
            if (task == null)
                return InvokeResultUtil.failure(BizStatusCodeEnum.FAILED.getCode(),"未查询到调度任务");

            if (queryAnalysisList(multipartFile , sourceType)){
                return InvokeResultUtil.failure(BizStatusCodeEnum.FAILED.getCode(),"该名称的物料已经存在");
            }

            int i = ZERO;
            int y = ZERO;
            int nThreads = TEN;
            String lineTxt;
            Long mainBid = sequenceNumUtil.getNum("");

            List<MsAnalysisMaterial> list = new LinkedList<>();
            InputStreamReader read = new InputStreamReader(multipartFile.getInputStream(), ENCODING);
            BufferedReader br = new BufferedReader(read);
            while ((lineTxt = br.readLine()) != null) {
                if (i == ZERO) {
                    i++;
                    continue;
                }else if (StringUtils.isEmpty(lineTxt.trim())){
                    continue;
                }
                list.add(MsAnalysisMaterial.generateMsAnalysisMaterial(sequenceNumUtil.getNum(""),mainBid,sourceType,
                        dispatchBid, executionBid, i, task.getProjectId(), multipartFile.getOriginalFilename(), lineTxt));
                i++;
            }

            int size = list.size();
            ExecutorService executorService = Executors.newFixedThreadPool(nThreads + ONE);
            List<Future<Integer>> futureList = new ArrayList<>(nThreads);
            for (int x = 0; x < nThreads; x++) {
                final List<MsAnalysisMaterial> finalList = list.subList(size / nThreads * x, size / nThreads * (x + 1));
                Callable<Integer> task1 = () -> {
                    msAnalysisMaterialService.saveBatch(finalList);
                    return ONE;
                };
                y = y + finalList.size();
                futureList.add(executorService.submit(task1));
            }

            final List<MsAnalysisMaterial> finalList = list.subList(y, size);
            if (!CollectionUtils.isEmpty(finalList)){
                Callable<Integer> task2 = () -> {
                    msAnalysisMaterialService.saveBatch(finalList);
                    return ONE;
                };
                futureList.add(executorService.submit(task2));
            }

            executorService.shutdown();
            read.close();
            Integer integer = insertFailRecords(sourceType);
            msAnalysisMaterialMainService.save(MsAnalysisMaterialMain.generateMsAnalysisMaterialMain(mainBid,sourceType,
                    multipartFile.getOriginalFilename(), integer));
            return InvokeResultUtil.success("文件解析成功");
        } catch (Exception e) {
            log.error("读取文件内容出错", e);
            e.printStackTrace();
            return InvokeResultUtil.failure(BizStatusCodeEnum.ERROR_SAVE.getCode(), "读取文件内容异常");
        }
    }

数据库异常:

Caused by : java.sql.SQLTransientConnectionException: HikariPool-1 
Connection is not available, request timed out after 30000ms

修改后数据库配置:

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://xx.xx.xx.169:3306/yyyy?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useAffectedRows=true&serverTimezone=Asia/Shanghai
    username: adminV1
    password: ENC(AK7UALIt1/5wqk62OIYtw+1JJN2FgaLE)
    # Hikari 连接池配置
    hikari:
      # 连接池中维护的最小空闲连接数
      minimum-idle: 20
      # 空闲连接存活最大时间,默认600000(10分钟)
      idle-timeout: 1800000
      # 连接池最大连接数,默认是10
      maximum-pool-size: 80
      # 此属性控制从池返回的连接的默认自动提交行为,默认值:true
      auto-commit: true
      # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
      max-lifetime: 1800000
      # 数据库连接超时时间,默认30秒,即30000
      connection-timeout: 60000
      #连接将被测试活动的最大时间量
      validation-timeout: 30000
      connection-test-query: SELECT 1
      connection-init-sql: SET NAMES utf8mb4
`cannotgetjdbcconnectionException:Failed to obtain JDBC connection; nested exception is java.sql.SQLTransientConnectionException` 这是一个典型的数据库连接异常,通常在Java中使用JDBC(Java Database Connectivity)进行数据库操作时遇到。这个异常表明程序试图从数据库获取连接,但是没有成功,原因可能是: 1. 数据库连接池可能已满:如果你的应用程序在并发请求下频繁地创建数据库连接,而连接池的大小有限,可能会耗尽所有的连接资源,导致无法获取新的连接。 2. 网络问题或服务器不可达:如果数据库服务器当前不可达或者网络连接不稳定,那么即使有空闲的连接也无法分配给应用程序。 3. 配置错误:数据库连接相关的配置(如URL、用户名、密码等)可能不正确,导致无法建立有效的连接。 4. SQLTransientConnectionException:这是一个SQL异常子类,通常表示一个暂时性的连接问题,例如数据库正在维护或者事务正在处理,连接被锁定。 为了解决这个问题,你可以尝试以下步骤: - 检查数据库连接配置是否正确。 - 确保数据库服务器正常运行,网络连接畅通。 - 检查数据库连接池大小和配置,是否有足够的连接来满足需求。 - 如果是应用程序代码的问题,检查是否在关闭连接后正确地归还到连接池,避免连接泄漏。 - 使用日志记录详细信息,以便定位问题发生的具体位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值