项目报错:No operations allowed after connection closed

项目报错:No operations allowed after connection closed

今天写web项目时又曝出了以前没解决的错误,今天仔细想想终于把他理解了

错误原因

  1. 在servlet里,当我创建完一个Dao层对象,并且调用根据主键返回数据库的一个对象的方法时,调用了connection一次,调用完成后就将它close了。
  2. 但接着我在servlet里获得这个对象时,我又需要调用这个Dao层对象的另一个方法,即删除我调用的这个对象,而他又需要去调用一次connection,这时,connection已经在刚才的方法中被关闭了,所以报错。
  3. (请忽略我Dao层的删除逻辑是传入整个对象再进去寻找删除)

BaseDao部分代码

private Connection connection = null;

    public Connection getConnection() throws Exception{
        if (connection == null){
            Class.forName(JDBC_DRIVER);
            connection = DriverManager.getConnection(DB_URL,USER,PASSWORD);
        }
        return connection;
    }

    public void closeConnection() throws Exception{
        if (connection != null){
            connection.close();
        }
    }

SuperBillsDao层部分代码

(SuperBillsDao extend BaseDao)

根据主键返回id的方法:

	//根据主键选择bill
    public SuperBills selectById(int billid) throws Exception{
        SuperBills superBills = null;
        Connection connection = this.getConnection();
        //获取数据库执行对象
        String sql = "select * from superbills where billid=?";
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.setInt(1,billid);
        //执行数据库语句
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            int id = rs.getInt(1);
            String name = rs.getString(2);
            String desc = rs.getString(3);
            int count = rs.getInt(4);
            BigDecimal price = rs.getBigDecimal(5);
            int ispayment = rs.getInt(6);
            int providerid = rs.getInt(7);
            String creator = rs.getString(8);
            String time = rs.getString(9);

            superBills = new SuperBills();
            superBills.setBillid(id);
            superBills.setProductname(name);
            superBills.setProductdesc(desc);
            superBills.setProductcount(count);
            superBills.setTotalprice(price);
            superBills.setIspayment(ispayment);
            superBills.setProviderid(providerid);
            superBills.setCreator(creator);
            superBills.setCreatetime(time);
        }
        rs.close();
        ps.close();
        closeConnection();
        return superBills;
    }

根据对象删除此对象的方法
(逻辑有问题,懒得改了)

    //删除bill
    public void delete(SuperBills superBills) throws Exception{
        Connection connection = this.getConnection();
        String sql = "delete from superbills where billid=?";
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.setInt(1,superBills.getBillid());
        ps.execute();
        ps.close();
        closeConnection();
    }

servlet代码

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        int id = Integer.parseInt(request.getParameter("billid"));
        SuperBillsDao superBillsDao = new SuperBillsDao();
        try {
            SuperBills superBills = superBillsDao.selectById(id);
            superBillsDao.delete(superBills);
            System.out.println("BillDelete is ok");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doPost");
        response.sendRedirect("BillListServlet");
    }

问题(冲突)代码

SuperBills superBills = superBillsDao.selectById(id);
superBillsDao.delete(superBills);

解决方法

try {
      SuperBills superBills = superBillsDao.selectById(id);
      SuperBillsDao secondDao = new SuperBillsDao();
      secondDao.delete(superBills);
      System.out.println("BillDelete is ok");
} catch (Exception e) {
   e.printStackTrace();
}

根据主键查询完后,connection已经被关闭,无法再调用
所以这里再开一个Dao,用于删除操作,有些臃肿和低效率
但很省事儿

总结

错误原因

前一次调用完connection后close掉了,同一个Dao层对象无法再使用connection

目前的解决方法

再new一个Dao对象,调用另外的方法
(不过调一个方法就要新建一个对象属实憨憨)
希望各位带佬有更好的解决方法请告诉我和同样没搞懂的朋友

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]和\[2\]中提到的异常"jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed."是由于连接关闭后仍然执行了数据库操作引起的。引用\[3\]中解释了这个异常的原因,即MySQL默认空闲8小时没有操作会自动断开连接。在C3P0连接池中,如果连接空闲超过8小时,MySQL会断开连接,但C3P0并不知道该连接已经失效。当有客户端请求连接时,C3P0会提供这个失效的连接,从而导致上述异常的出现。 解决这个问题的方法是在Spring Boot的application.properties文件中增加DBCP配置。DBCP是Apache Commons DBCP连接池的一种实现,可以用来管理数据库连接。通过配置DBCP的相关参数,可以避免连接空闲超过8小时被MySQL断开的问题,从而解决上述异常。 请注意,具体的DBCP配置参数可能因使用的数据库和连接池的版本而有所不同。你可以根据自己的需求和环境进行相应的配置。 #### 引用[.reference_title] - *1* *3* [解决MySQLNonTransientConnectionException的问题](https://blog.csdn.net/wwwzhouzy/article/details/118710071)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [关于java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed.的解决方案](https://blog.csdn.net/weixin_62338217/article/details/127405066)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值