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设置字段搞反了