Mysql异常No operations allowed after statement closed

Mysql异常No operations allowed after statement closed

在这里插入图片描述

复现

在做一个商品管理时,删除商品遇到了这个问题,

当时的删除代码

    //delete
    public Boolean deleteGoods(Integer id) {
        conn = DBUtil.getConn();
        String deleteSql = "DELETE FROM goods_info WHERE goods_info.goods_id=?;";
        try {
            pre.setInt(1, id);
            pre = conn.prepareStatement(deleteSql);
            return pre.executeUpdate() > 0;
        } catch (SQLException e) {
            System.out.println("删除异常" + e);
        } finally {
            DBUtil.release(rs, pre, conn);
        }
        return false;
    }

起初在网上查,都是说

  • 之所以会出现这个异常,是因为Mysql在5以后针对超长时间DB连接做了一个处理,那就是如果一个DB连接在无任何操作情况下过了8个小时后,Mysql会自动把这个连接关闭。所以使用连接池的时候虽然连接对象还在但是链接数据库的时候会一直报这个异常。解决方法很简单在Mysql的官方网站上就可以找到。 有两个方法
    第一种是在DB连接字符串后面加一个参数。
    这样的话,如果当前链接因为超时断掉了,那么驱动程序会自动重新连接数据库。

    jdbc:mysql://localhost:3306/makhtutat?autoReconnect=true
    

    不过Mysql并不建议使用这个方法。因为第一个DB操作失败的后,第二DB成功前如果出现了重新连接的效果。

      conn.createStatement().execute(
        "UPDATE checking_account SET balance = balance - 1000.00 WHERE customer='Smith'");
      conn.createStatement().execute(
        "UPDATE savings_account SET balance = balance + 1000.00 WHERE customer='Smith'");
      conn.commit();
    

    当然如果出现了重新连接,一些用户变量和临时表的信息也会丢失。 ###另一种方法是Mysql推荐的,需要程序员手动处理异常。

    Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        int retryCount = 5;
        boolean transactionCompleted = false;
        do {
            try {
                conn = getConnection(); // assume getting this from a
                                        // javax.sql.DataSource, or the
                                        // java.sql.DriverManager
                conn.setAutoCommit(false);
                retryCount = 0;
                stmt = conn.createStatement();
                String query = "SELECT foo FROM bar ORDER BY baz";
                rs = stmt.executeQuery(query);
                while (rs.next()) {
                }
                all.close()
                transactionCompleted = true;
            } catch (SQLException sqlEx) {
                String sqlState = sqlEx.getSQLState();
               // 这个08S01就是这个异常的sql状态。单独处理手动重新链接就可以了。
                if ("08S01".equals(sqlState) || "40001".equals(sqlState)) 
                    {                
                        retryCount--;            
                     } else {                
                         retryCount = 0;            
                         }        
             } finally {            
                     all close:        
                 }    
          } while (!transactionCompleted && (retryCount > 0));}
    }
    
  • Mysql在5以后针对超长时间DB连接做了一个处理,服务器“wait_timeout”默认8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。所以使用连接池的时候虽然连接对象还在但是链接数据库的时候会一直报这个异常
    
    解决办法:
    
      进入MySQL查看设置的时间,show global variables like 'wait_timeout';
    
    1、增加MySQL的 wait_timeout 的时间
    
    windows环境下,修改mysql5的配置文件“my.ini”(mysql5 installation dir),增加一行:wait_timeout=1814400  (修改时间为21天),在Linux下叫my.cnf,该文件位于/etc/my.cnf
    
    或者,登录MySQL,使用SQL语句修改,set global wait_timeout=1000000

我在MySQL中试了set global wait_timeout=1000000;这个方法没用

解决方法

我重新阅读了代码,发现了错误

//delete
    public Boolean deleteGoods(Integer id) {
        conn = DBUtil.getConn();
        String deleteSql = "DELETE FROM goods_info WHERE goods_info.goods_id=?;";
        try {
            pre = conn.prepareStatement(deleteSql);
            pre.setInt(1, id);//this
            return pre.executeUpdate() > 0;
        } catch (SQLException e) {
            System.out.println("删除异常" + e);
        } finally {
            DBUtil.release(rs, pre, conn);
        }
        return false;
    }

我把pst设置字段搞反了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值