项目场景:

提示:这里简述项目相关背景:

项目场景:Springboot框架,hibernate框架,mysql数据库,hikari连接池


问题描述

项目部署到生产环境启动20分钟左右就会报错,报链接池链接数据库超时;
HikariPool-1 - Connection is not available, request timed out after 30001ms.

dao代码展示:

这是一种比较老并且恶心的sql写法,也是第一次接触这种框架
@Override
public List<BContractApplyListVO> selectContractList( String parentId) {
    StringBuffer sql = new StringBuffer();
    sql.append("SELECT * FROM ( select null AS id, a.contract_id as contractId\n" +
        "      ,a.contract_code as contractCode\n" +
        "      ,a.project_name as projectName\n" +
        "      ,a.parent_contract_id as parentContractId\n" +
        "      ,a.customer_name as customerName\n" +
        "      ,a.device_name as deviceName\n" +
        "      ,a.contract_type as contractType\n" +
        "      ,a.create_user as createUser\n" +
        "      ,a.create_user_name as createUserName\n" +
        "      ,a.flow_process_id as flowProcessId  \n" +
        "      ,a.contract_title as contractTitle\n" +
        "      ,a.verify_status as verifyStatus\n" +
        "      ,a.create_time as createTime\n" +
        "      ,a.execute_status as executeStatus  \n" +
        "      ,if(isnull(t.subNumber),'0','1') AS subExecuteStatus\n" +
        "     ,'0' AS appType,a.del_flag AS delFlag,a.tenant_id AS tenantId,a.business_type AS businessType,a.customer_credit_code AS customerCreditCode,a.project_id as projectId\n" +
        "  from b_contract_apply a\n" +
        "  left join (\n" +
        "select parent_contract_id,count(*) AS subNumber\n" +
        "from b_contract_apply bca \n" +
        "where bca.parent_contract_id IS NOT NULL \n" +
        "and bca.execute_status = 0 \n" +
        "GROUP BY bca.parent_contract_id HAVING COUNT(*) > 0 \n" +
        "  ) t on t.parent_contract_id = a.contract_id \n");
    sql.append(" UNION ALL " +
        "SELECT                                     \n" +
        "  bccf.id AS id,                          \n" +
        "  bccf.contract_id AS contractId,         \n" +
        "  bccf.contract_code AS contractCode,     \n" +
        "  bccf.project_name AS projectName,       \n" +
        "  '' AS parentContractId,                 \n" +
        "  bccf.customer_name AS customerName,     \n" +
        "  bccf.device_name AS deviceName,         \n" +
        "  bccf.contract_type AS contractType,     \n" +
        "  bccf.create_user AS createUser,         \n" +
        "  bccf.flow_process_id as flowProcessId,  \n" +
        "  bccf.create_user_name AS createUserName,\n" +
        "  bccf.contract_name AS contractTitle,    \n" +
        "  bccf.verify_status AS verifyStatus,     \n" +
        "  bccf.create_time AS createTime,         \n" +
        "  bccf.execute_status AS executeStatus,   \n" +
        "  '' AS subExecuteStatus,                 \n" +
        "  '1' AS appType,                         \n" +
        "  bccf.del_flag AS delFlag,               \n" +
        "  bccf.tenant_id AS tenantId,                         \n" +
        "  '' AS businessType,bccf.customer_file_name AS customerCreditCode,'' AS projectId          \n" +
        " FROM b_contract_change_flow bccf ) ai     \n" +
        " where ai.delFlag = 0 ");
    if (!StringUtils.isEmpty(parentId)){
        sql.append("and ai.parentContractId = '").append(parentId).append("'");
    }else {
        sql.append(" and ai.verifyStatus = 1 and ai.executeStatus = 0");
    }
    Query query = entityManager.createNativeQuery(sql.toString());
    List<BContractApplyListVO> list = query.unwrap(NativeQuery.class).setResultTransformer(new FluentHibernateResultTransformer(BContractApplyListVO.class)).list();
    EntityManagerFactoryUtils.closeEntityManager(this.entityManager);
    return list;
}

原因分析:

问题的原因报错是说的连接池链接不上数据库,从而导致系统崩溃,这个微服务所有的功能都不能够正常运行.


这个项目有非常多的定时任务

hikaricp連接sqlite hikaripool连接超时_数据库


一直想着是不是定时任务太多,链接池数量太少,没有自动提交链接的配置呢?

与是就百度各种查找修改链接池配置的问题; 但是测试后发现结果并不解人意, 但是发现由原来20分钟报错延迟到了2小时之后.就觉得有点作用.然后又把定时任务由3分钟一次改到10分钟一次. 报错时间又延长到8小时

这个解决办法就是治标不治本!

解决方案:

@Transactional:事物注解

看到这里很多同学就会问?这个跟事物有啥关系呢.

那确实就是有关系,这种操作数据库的JPA可以说是非常的老的,它不像现在的mybatis,mybatis-Plus.这些框架底层都是会在对表进行增删改查之后都是会提交资源,断开链接的.

细心的同学看dao帖出来的代码就能看到,这个有EntityManagerFactoryUtils.closeEntityManager(this.entityManager) 去关闭链接呀! 因为是SpringBoot的框架,这个关闭链接是没有用的!我们需要用事物,去帮我们提交

这个问题也是上到生产,看到领导被客户叼.自己也是被领导一顿好叼啊. 但是呢挨叼也是工作的一部分呀! 自己太菜了!