章
目
录
问题现象
使用SpringBoot整合Mybatis-Plus多数据源使用多线程执行mysql数据库新增和更新操作时,出现如下报错:
报错类似如下:
……
at com.sf.hlcs.sda.service.impl.ScdDeviceStatusLogServiceImpl$$EnhancerBySpringCGLIB$$93d0a0f0.insertOrUpdateLog(
at com.sf.hlcs.sda.runnable.DeviceStatusLogRunnable.run(DeviceStatusLogRunnable.java:30) ~[classes/:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_202]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_202]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_202]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_202]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_202]
Caused by: java.sql.SQLTransientConnectionException: master – Connection is not available, request timed out after 10014ms.
报错原因
Mybatis-Plus默认使用的是 HikariPool
数据库连接池,解释下报错原因就是没有可用数据库连接,获取连接等待超时,我这里是10s中超时(很奇怪,配置的明明是30s),看下在apollo中的部分相关配置(如果没用apollo,应该在application.yml文件中):
这里设置的connection-timeout
超时时间是50s,而Mybatis-Plus中的HikariCpConfig
类中默认的是30s,这里应该以我们配置的为准,奇怪的就是为什么我这10s就报超时了,还没搞明白!
处理过程
第一反应应该是配置数据库的连接池数量超过上限,或者哪里的连接没有释放,但是发现通过doDBA监测Mysql发现连接数量没有超上限,是正常的:
如果你的存在手工创建session,使用完后没关闭的,需要在finally中调用session.close()
关闭即可。我这里应该不是这个原因
第二个原因可能就是数据源connection-timeout
的超时时长和max-pool-size
的的配置问题,可以加大时长,增多连接数量。但我这还是不是这个原因。
这时候我发现在我们使用了多个数据源,在apollo中有多个数据源配置,这个数据源的配置信息这部分没起作用,而是使用了主库的相关配置,导致这里的连接超时时间变为了主库数据源的配置时间,也就是10s,那么问题就找到了,然后修改了主库相关的配置信息,发现连接数量立马就上来了,自然也就不再报错了:
总结
所以SQLTransientConnectionException: Connection is not available, request timed out after 10014ms
问题报错的原因还是上面说的原因,但是造成这个原因的可能性又有很多,得根据自己的实际情况去排查并解决问题。