Connection is not available 解决方案

发布时间 2023-06-02 14:16:15作者: lanwf

在最近程序中 发现时不时”死机,无响应“的情况,经查看日志得知

用的是官方提供的 jdbcTemplete 工具

 数据源连接池里面的资源全部不可用了, 是什么原因呢?

 

经查悉,原来是有人在写sql的时候,进行了全表查询并且数据较大,导致响应未果,多次请求以后就消耗掉了所有的连接池里面的资源  都在卡住状态。导致无链接可用才引发了这个结果

 

方法一 在jdbc中用自带的 queryTimeOut 参数设置 响应时间,超过设置的时间无响应,就会自动抛异常释放资源

方法二  重新赋值jdbcTemplet 的 赋值 方法,  增加读取时间设置,超过这个时间 数据还没读取完毕,就手动抛出异常释放资源

 

代码

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;
    }