Connection is not available 解决方案
最近程序中发现时不时”死机,无响应“的问题,必须重启服务器才能解决,用的是官方提供的 jdbcTemplate 工具,经查看日志得知

数据源连接池里面的资源全部不可用了, 是什么原因呢?
经查悉,原来是有人在写sql的时候,进行了全表查询并且数据较大,导致响应未果,多次请求以后就消耗掉了所有的连接池里面的资源 都在卡住状态。导致无链接可用才引发了这个结果
方法一 在jdbc中用自带的 queryTimeOut 参数设置 响应时间,超过设置的时间无响应,就会自动抛异常释放资源
方法二 重新赋值jdbcTemplate 的 赋值 方法, 增加读取时间设置,超过这个时间 数据还没读取完毕,就手动抛出异常释放资源
用重新的JdbcTemplateWapper 替代 JdbcTemplate
代码
public class JdbcTemplateWapper extends JdbcTemplate {
/**
* 查询超时时间
*/
public static int queryTimeout = 30;
//数据读取超时时间 ms
public static long readTimeOut = 10000;//ms
private final JdbcTemplate jdbcTemplate;
public JdbcTemplateWapper(JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
this.jdbcTemplate.setQueryTimeout(queryTimeout);
}
@Override
public <T> List<T> queryForList(String sql, Class<T> elementType) throws DataAccessException {
return jdbcTemplate.query(sql, new SingleColumnRowMapperWapper(elementType));
}
@Override
public List<Map<String, Object>> queryForList(String sql) throws DataAccessException {
return jdbcTemplate.query(sql, new ColumnMapRowMapperWapper());
}
@Override
public Map<String, Object> queryForMap(String sql) throws DataAccessException {
return jdbcTemplate.queryForMap(sql);
}
public class ColumnMapRowMapperWapper extends ColumnMapRowMapper{
long startDate = System.currentTimeMillis();
@Override
protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
if(startDate+readTimeOut < System.currentTimeMillis()) throw new SQLException("数据读取超时");
return super.getColumnValue(rs, index);
}
}
public class SingleColumnRowMapperWapper<T> extends SingleColumnRowMapper<T>{
SingleColumnRowMapperWapper(Class<T> requiredType){
super(requiredType);
}
long startDate = System.currentTimeMillis();
@Override
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
if(startDate+readTimeOut < System.currentTimeMillis()) throw new SQLException("数据读取超时");
return super.mapRow(rs, rowNum);
}
}
测试调用
public static JdbcTemplate jdbc(){
if(JDBC_TEMPLATE == null){
synchronized (CommonUtils.class){
if(JDBC_TEMPLATE == null){
JDBC_TEMPLATE = new JdbcTemplateWapper(SpringApplicationContextUtil.getBean(JdbcTemplate.class));
}
}
}
return JDBC_TEMPLATE;
}
超过queryTimeOut 会报以下错误

超过读取时间10s 会报以上 手动抛的错误

成功解决数据库链接资源消耗完 卡死问题
本文来自博客园,作者:lanwf,转载请注明原文链接:https://www.cnblogs.com/lccsdncnblogs/p/17451639.html

浙公网安备 33010602011771号