Cause: HikariPool-1 - Connection is not available, request timed out after 30000ms.

问题描述:有一个定时任务,每隔一段时间往接口推送一批数据,将推送成功的数据状态码改成1,但是在部署运行一天后就没有收到数据了。看了下日志文件报错:

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 30000ms.

第一时间想到的是数据库连接未释放,然后我就先去检查了配置文件,发现好像没什么问题,之前的接口也一直都是这样的配置

spring:
    jpa:
        open-in-view: false

于是我又把hikari连接池的默认配置修改了一下,在网上找的大部分教程都是教我们修改这个配置,但是我改了之后也没啥效果,唯一的效果就是我把最大连接数改大之后,开始是运行一天报错的,现在能运行三天了,然后一如既往的报错。

后面我去查看oracle的连接状态

select program,machine,count(*) from v$session group by machine,program order by 3 desc;

查到有一个连接有一千多条,这一看就不正常了。那问题大概率就是连接未释放,然后再查看一下具体的状况。

select PROGRAM,MACHINE,STATUS,LOGON_TIME,TIME_REMAINING_MICRO from v$session where PROGRAM='JDBC Thin Client' and MACHINE='epcfileserver01';
--这里的PROGRAM跟MACHINE是上一步查出来的那个值

字段解释:更多字段解释参考官方文档V$会话 (oracle.com)

PROGRAM:操作系统程序名

MACHINE:操作系统计算机名

STATUS:会议状态

  • ACTIVE- 当前正在执行 SQL 的会话

  • INACTIVE- 会话处于非活动状态,没有配置的限制或尚未超过配置的限制

  • KILLED- 标记为被杀死的会话

  • CACHED- 会话临时缓存以供 Oracle*XA 使用

  • SNIPED- 已超出某些配置限制(例如,为资源管理器使用者组指定的资源限制或在用户配置文件中指定的idle_time)的非活动会话。此类会话将不允许再次激活。

LOGON_TIME:登陆时间

TIME_REMAINING_MICRO:

  • > 0 当前等待的剩余时间量(以微秒为单位)

  • 0 当前等待已超时

  • -1 会话可以在当前等待中无限期等待

  • NULL 会话当前未等待

那么是什么导致了这个问题呢,我想了下会不会是我设置定时任务的while循环里面出问题了,while循环里面我用的是new RestTemplate()去调用接口,然后我又去搜了一下它的一个销毁,结果发现这玩意好像是不会自己销毁的。所以可能是每一次while循环都会去新建一个连接未释放,最终导致报错。于是改了下代码,不再去new一个RestTemplate了而是去创建个bean。目前我改了之后暂时没报错再等几天试试。每个人的问题可能都不一样还是得细心去找

一周过去了,接口正常运行,没有报错了,只需要把bean对象放在容器里,然后执行完的时候把容器关掉,bean对象就会自动销毁,这样连接也就释放了。

@Configuration
public class RestTemplateConfiguration {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
}

//RestTemplate restTemplate = new RestTemplate();不再去new一个对象
            while (true){
                //创建容器
                AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(RestTemplateConfiguration.class);
                RestTemplate restTemplate = context.getBean(RestTemplate.class);
                restTemplate.getForEntity(requestURL, String.class);
                //关闭容器后bean自动销毁
                context.close();
                log.info("一次插入结束,线程休眠一小时");
                Thread.sleep(3600000);
                log.info("休眠结束,启动定时推送");
            }

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值