有个需求,就是需要获取到mysql数据库中的某个表的所有字段名称,然后写了个链接数据库的接口,但是问题就出现了
前端一直请求这个接口的时候,连接池顶不住压力,请求了没几次,程序就异常崩溃了,这是因为没有正常的关闭这个连接导致的。
报错信息如下:
一开始我还以为是hikari的资源不够导致的,因此加上了下面的配置,将hikari的连接池配置了很大,但是经过测试之后,他的连接数量只增不减,这就导致了程序会异常终止,然后加上了hikari的连接泄露检测,只要超过两秒的连接占用就会被记录下来。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${DB_HOST:localhost}:3306/${DB_DATABASENAME:hwtswes}?serverTimezone=GMT%2b8
username: root
password: root
hikari:
maximum-pool-size: 20 #连接池中允许的最大连接数 作用: 限制连接池中同时存在的最大连接数。超过这个数量的连接请求将被阻塞或超时。
minimum-idle: 12 # 连接池中保持的最小空闲连接数,作用: 确保连接池中至少有这么多空闲连接。即使没有连接请求,也会保持这个数量的连接处于空闲状态。
idle-timeout: 30000 #空闲连接在被回收之前允许保持空闲状态的最长时间(毫秒) 作用: 如果连接空闲时间超过这个值,且当前空闲连接数超过 minimum-idle,则这个连接会被关闭。
connection-timeout: 30000 #获取连接的最大等待时间(毫秒) 作用: 在连接池中没有可用连接时,客户端等待连接可用的时间。如果超时,则抛出 SQLException。
max-lifetime: 1800000 #连接池中每个连接允许存活的最长时间(毫秒) 作用: 任何连接在池中存活时间超过这个值后都会被回收,即使它没有处于空闲状态。该值应比数据库或基础设施的连接超时稍短1800000(30min)
leak-detection-threshold: 2000 #启用连接泄露检测,连接泄露检测阈值为2秒,任何超过2秒连接占用将被记录,有助于找到没有正确关闭连接的代码路径
然后就找到了这句错误代码。
DatabaseMetaData metaData = jdbcTemplate.getDataSource().getConnection().getMetaData();
解决方法:我写的是不管他用没用,最后都要释放这个连接,就写了这个方法。
public DatabaseMetaData getDatabaseMetaData() throws SQLException{
Connection connection =null;
DatabaseMetaData metaData = null;
try {
connection = jdbcTemplate.getDataSource().getConnection();
metaData = connection.getMetaData();
} finally {
if (connection!=null){
try {
connection.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
return metaData;
}
然后将错误代码改为这个就OK了
DatabaseMetaData metaData = getDatabaseMetaData();
然后再启动程序,错误完美解决!