2 nicholaskg NicholasKg 于 2016.01.24 10:46 提问

在界面上连续按F5刷新Tomcat报错,显示连接池已满

错误信息:org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
Tomcat与数据库使用连接池,封装在一个类里面:
public class BaseDAO {

private Connection conn = null;
private ResultSet rs = null;
private Statement stmt = null;
private PreparedStatement pstmt = null;


//1)、获取数据库连接对象
private Connection getConnection(){
        try {
            Context context = new InitialContext();
            DataSource dataSource = (DataSource)context.lookup("java:comp/env/jdbc/sms");
            conn = dataSource.getConnection();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return this.conn;
}


//2)、获得结果集
public ResultSet executeQuery(String sql){
    try {
        conn = getConnection();
        stmt = conn.createStatement();
        rs = stmt.executeQuery(sql);
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return rs;
}

/*
 * 执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数
 */
public ResultSet executeQuery(String sql,Object ... paramValues){
    try {
        conn = getConnection();
        pstmt = conn.prepareStatement(sql);
        if(paramValues != null){
            for (int i = 0; i < paramValues.length; i++) {
                 pstmt.setObject((i+1), paramValues[i]);
            }
        }
        rs = pstmt.executeQuery();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return rs;
}


//3)、用来执行一个不需要置换参数的更新(插入、更新或删除)操作。
public int executeUpdate(String sql){
    int affectedRows = 0;
    try {
        conn = getConnection();
        stmt  = conn.createStatement();
        affectedRows = stmt.executeUpdate(sql);
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        closeAll(null,stmt,null,conn);
    }
    return affectedRows;
}

//用来执行一个需要置换参数的更新(插入、更新或删除)操作。
public int executeUpdate(String sql,Object ... paramValues){
    int affectedRows = 0;
    try {
        conn = getConnection();
        pstmt = conn.prepareStatement(sql);
        if(paramValues != null){
            for (int i = 0; i < paramValues.length; i++) {
                 pstmt.setObject((i+1), paramValues[i]);
            }
        }
        affectedRows = pstmt.executeUpdate();
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        closeAll(null,null,pstmt,conn);
    }
    return affectedRows;

}

//(5)通用查询工具方法
public List<Map<Object,Object>> query(String sql,Object ...paramValues){
    List<Map<Object,Object>> list = new ArrayList<Map<Object,Object>>();
    try {
        conn = getConnection();
        pstmt = conn.prepareStatement(sql);
        if(paramValues != null){
            for (int i = 0; i < paramValues.length; i++) {
                 pstmt.setObject((i+1), paramValues[i]);
            }
        }
        rs = pstmt.executeQuery();
        ResultSetMetaData rsmd = rs.getMetaData(); //获取元数据

        while(rs.next()){
            Map<Object,Object> map = new HashMap<Object,Object>();
            for (int j = 1; j <= rsmd.getColumnCount(); j++) {
                //获取列名
                String columnLabel = rsmd.getColumnLabel(j);
                //根据列名从结果集中获取对应的列值
                Object columnValue = rs.getObject(columnLabel);
                map.put(columnLabel, columnValue);
            } //end for
            list.add(map);
        }//end while
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
        closeAll(rs,null,pstmt,conn);
    }
    return list;
}

//4)、释放资源
public void closeAll(ResultSet rs,Statement stmt,PreparedStatement pstmt,Connection conn){
    if(rs!=null){
        try{
            //关闭存储查询结果的ResultSet对象
            rs.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        rs = null;
    }
    if(stmt!=null){
        try{
            //关闭负责执行SQL命令的Statement对象
            stmt.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    if(pstmt!=null){
        try{
            //关闭负责执行SQL命令的PreparedStatement对象
            pstmt.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    if(conn!=null){
        try{
            //将Connection连接对象还给数据库连接池
            conn.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

}

执行查询时ResultSet的实例rs在调用后就关闭了,但是无法关闭Connection的实例conn 和Statement的实例stmt

1个回答

rui888
rui888   Ds   Rxr 2016.01.24 15:10
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
F5刷新你所不知道的知识
502 Bad Gateway编辑 502 Bad Gateway是指错误网关;无效网关;在互联网中表示一种网络错误。表现在WEB浏览器中给出的页面反馈。 中文名 错误网关 外文名 502 Bad Gateway 类    型 概念 类    别 网络 网    关
在浏览器中,按f5(浏览器中的刷新按钮),与f5+ctrl 、回车的区别
简言之: 回 车 : f5 : 发送request请求,但是会用缓存。会返回304. f5+ctrl:发送request请求,且不用缓存,完全是获取一份全新的内容。f5会在request Header中增加 If-Modified-Since: Fri 30 Nov 2007 00:00:00 GMT If-Modified-Since/If-None-Matchf5
通过js模拟用户按F5刷新页面效果
通过js代码达到与用户按下键盘上F5键相同的效果(刷新整个浏览器窗口)有两种方式: 1、window.location.href = window.location.href; 2、window.location.replace(window.location.href);
关于pjax的问题,前进后退正常,f5刷新不对,怎么破
最近在做单页面的web应用,网站比较小,所以没有别的框架,用的jquery+ajax,但是浏览器前进后退有问题,于是百度一下可以使用pjax进行前进后退。 然后做了个例子,确实可以了,但是紧接着问题来了,如果进行局部渲染之后直接按f5,则页面只剩下了局部刷新的页面,其他页面元素都没有了, 网上也看了好些人说这个问题,也有人回答了问题,但是答案都是要不说的根本就不是这个问题,要不就是根本看不懂,
F5刷新和Ctrl+F5强制刷新
IE里F5和Ctrl+F5区别一个是刷新,一个是强制刷新 按F5有时候一些内容是不会被更新的,而CTRL+F5则所有内容都会被更新. 具体区别是:F5通常只是刷新本地缓存;Ctrl+F5可以把INTERNET临时文件夹的文件删除再重新从服务器下载,也就是彻底刷新页面了
F5刷新与在地址栏按回车的区别(待整理)
先来说“刷新”,它是在你现有页 面的基础上,检查网页是否有更新的内容。在检查时,会保留之前的一些变量的值,因此有 可能会造成刷新后网页出现错误,或者打不开的情况;“转到”和在地址栏回车,则相当于 你重新输入网页的URL访问,这种情况下,浏览器会尽量使用已经存在于本机中的缓存。 也就是说,“刷新” 是取网页的新内容来更新本机缓存,在更新的同时保留之前的一些变 量;“转到”则是一种全新的访问
iframe结构的网站按F5刷新子页面的实现方式
有的网站或者后台系统由于页面有公共的部分,比如菜单,会把公共的部分放在一个页面,这里称之为父页面,而把具体的内容放入一个iframe中,之后的请求改变iframe的内容。但是这样会有一个问题,因为浏览器的url是父页面的链接,当你按F5刷新的时候,并不是刷新iframe所对应的页面,而是刷新了父页面,使系统回到了最初的位置,这样对操作是很不爽的。 比如,页面的格式是这样的。 其中ind
jsp中页面定时自动刷新跳转和按F5刷新跳转
定时自动刷新跳转(5秒后跳到index.html页面): 键盘按键控制跳转: document.onkeydown = function(e) {//键盘按键控制 e = e || window.event; if ((e.ctrlKey && e.keyCode == 82) || e.keyCode == 116) { //ctrl+R和F5刷新 window
MVC防止F5刷新重复提交数据
Controller代码如下: // // GET: /Home/ [HttpGet, ImportModelStateFromTempData] public ActionResult Register() { return View(); } [HttpPost, Ex
页面按F5刷新重复提交表单数据的解决办法
直接让表单按钮失效,从而保证一个用户对于一个表单只能提交一次 一次提交后把表单清空,在后台逻辑上进行判断,从而区分是否重复提交以上两点为理论,最后解决是通过form表单提交后直接重定向到相同的url,实现页面刷新且展示提交数据的 即: 提交后执行页面重定向,这就是所谓的Post-Redirect-Get (PRG)模式。简言之,当用户提交了表单后,你去执行一个客户端的重定向,转到提交成功信息页面