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