【异常】Caused by: java.sql.SQLTransientConnectionException: HikariPool-1

一、异常出现的场景

  一次线上订单历史数据字段刷新操作,3张表100多万数据。由于同步更新太慢大概20分钟以上,所以采用异不的方式。代码如下:

private void batchUpdate(List<SaasOrderRecordDataForUpdate> saasOrderRecordDataForUpdateList, List<SaasServiceOrderInfoDataForUpdate> saasServiceOrderInfoDataForUpdateList, List<OrderGoodsDataForUpdate> orderGoodsDataForUpdateList, List<OrderAdditionCostInfoDataForUpdate> orderAdditionCostInfoDataForUpdateList) {
        List<Future> asyncResultList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(saasOrderRecordDataForUpdateList)) {
            int size = saasOrderRecordDataForUpdateList.size();
            int count = size / 5000;
            for (int i = 0; i <= count; i++) {
                List<SaasOrderRecordDataForUpdate> subList = null;
                if (i == count) {
                    if (5000 * i < size) {
                        subList = saasOrderRecordDataForUpdateList.subList(5000 * i, size);
                    }
                } else {
                    subList = saasOrderRecordDataForUpdateList.subList(5000 * i, 5000 * (i + 1));
                }

                if (CollectionUtils.isNotEmpty(subList)) {
                    Future future = dataRefreshJobServiceForAsync.batchUpdateSaasOrderRecordDataForUpdate(subList);
                    asyncResultList.add(future);
                }
            }
        }
        XxlJobLogger.log("批量更新订单数:{}", saasOrderRecordDataForUpdateList.size());
        if (CollectionUtils.isNotEmpty(saasServiceOrderInfoDataForUpdateList)) {
            int size = saasServiceOrderInfoDataForUpdateList.size();
            int count = size / 5000;
            for (int i = 0; i <= count; i++) {
                List<SaasServiceOrderInfoDataForUpdate> subList = null;
                if (i == count) {
                    if (5000 * i < size) {
                        subList = saasServiceOrderInfoDataForUpdateList.subList(5000 * i, size);
                    }
                } else {
                    subList = saasServiceOrderInfoDataForUpdateList.subList(5000 * i, 5000 * (i + 1));
                }

                if (CollectionUtils.isNotEmpty(subList)) {
                    Future future = dataRefreshJobServiceForAsync.batchUpdateSaasServiceOrderInfoDataForUpdate(subList);
                    asyncResultList.add(future);
                }
            }

        }
        XxlJobLogger.log("批量更新订单服务数:{}", saasServiceOrderInfoDataForUpdateList.size());
        if (CollectionUtils.isNotEmpty(orderGoodsDataForUpdateList)) {
            int size = orderGoodsDataForUpdateList.size();
            int count = size / 5000;
            for (int i = 0; i <= count; i++) {
                List<OrderGoodsDataForUpdate> subList = null;
                if (i == count) {
                    if (5000 * i < size) {
                        subList = orderGoodsDataForUpdateList.subList(5000 * i, size);
                    }
                } else {
                    subList = orderGoodsDataForUpdateList.subList(5000 * i, 5000 * (i + 1));
                }

                if (CollectionUtils.isNotEmpty(subList)) {
                    Future future = dataRefreshJobServiceForAsync.batchUpdateOrderGoodsDataForUpdate(subList);
                    asyncResultList.add(future);
                }
            }

        }
        XxlJobLogger.log("批量更新订单商品数:{}", orderGoodsDataForUpdateList.size());
        if (CollectionUtils.isNotEmpty(orderAdditionCostInfoDataForUpdateList)) {
            int size = orderAdditionCostInfoDataForUpdateList.size();
            int count = size / 5000;
            for (int i = 0; i <= count; i++) {
                List<OrderAdditionCostInfoDataForUpdate> subList = null;
                if (i == count) {
                    if (5000 * i < size) {
                        subList = orderAdditionCostInfoDataForUpdateList.subList(5000 * i, size);
                    }
                } else {
                    subList = orderAdditionCostInfoDataForUpdateList.subList(5000 * i, 5000 * (i + 1));
                }

                if (CollectionUtils.isNotEmpty(subList)) {
                    Future future = dataRefreshJobServiceForAsync.batchUpdateOrderAdditionCostInfoDataForUpdate(subList);
                    asyncResultList.add(future);
                }
            }
        }
        XxlJobLogger.log("批量更新订单附加费数:{}", orderAdditionCostInfoDataForUpdateList.size());

        if (CollectionUtils.isNotEmpty(asyncResultList)) {
            for (Future asyncResult : asyncResultList) {
                try {
                    asyncResult.get();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
View Code

本地库刷新没问题,但是到了线上库就出现如下异常:

### Error updating database.  Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30005ms.
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30005ms.
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
    at sun.reflect.GeneratedMethodAccessor380.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
    ... 24 more
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30005ms.
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81)
    at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:82)
    at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:68)
    at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:338)
    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:84)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
    at sun.reflect.GeneratedMethodAccessor381.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
    at com.sun.proxy.$Proxy521.update(Unknown Source)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
    ... 28 more
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30005ms.
    at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:669)
    at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:183)
    at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:148)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128)
    at com.zaxxer.hikari.HikariDataSource$$FastClassBySpringCGLIB$$eeb1ae86.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
    at com.zaxxer.hikari.HikariDataSource$$EnhancerBySpringCGLIB$$f68c05a.getConnection(<generated>)
    at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78)

二、解决办法

通过异常可以发现是由于获取不到数据库连接导致,猜测是连接数不够的问题,所以修改HikariPool连接池配置,就解决了

修改前:

spring:
  datasource:
    hikari:
      connection-test-query: SELECT 1 FROM DUAL
      connection-timeout: 30000
      maximum-pool-size: 20
      max-lifetime: 1800000
      minimum-idle: 5
      connection-init-sql: SET NAMES utf8mb4

修改后:

spring:
  datasource:
    hikari:
      connection-test-query: SELECT 1 FROM DUAL
      connection-timeout: 600000
      maximum-pool-size: 500
      max-lifetime: 1800000
      minimum-idle: 20
      validation-timeout: 3000
      idle-timeout: 60000
      connection-init-sql: SET NAMES utf8mb4
原文地址:https://www.cnblogs.com/756623607-zhang/p/11716897.html