Java JDBC MySQLexception:“ResultSetclosures后不允许操作”

我已经在这工作了将近一天半了,我似乎无法解决这个错误。 我不知道为什么ResultSet被closures。 也许你们中的一些人可以帮助我。

MySQLDatabase:

package net.gielinor.network.sql; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public abstract class MySQLDatabase { private String host; private String database; private String username; private String password; private Connection connection = null; private Statement statement; public MySQLDatabase(String host, String database, String username, String password) { this.host = host; this.database = database; this.username = username; this.password = password; } public abstract void cycle() throws SQLException; public abstract void ping(); public void connect() { try { Class.forName("com.mysql.jdbc.Driver").newInstance(); connection = DriverManager.getConnection(String.format("jdbc:mysql://%s/%s", host, database), username, password); statement = connection.createStatement(); } catch (Exception e) { e.printStackTrace(); } } public void ping(String table, String variable) { try { statement.executeQuery(String.format("SELECT * FROM `%s` WHERE `%s` = 'null'", table, variable)); } catch (Exception e) { connect(); } } public ResultSet query(String query) throws SQLException { if (query.toLowerCase().startsWith("select")) { return statement.executeQuery(query); } else { statement.executeUpdate(query); } return null; } public Connection getConnection() { return connection; } } 

MySQLHandler

 package net.gielinor.network.sql; import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; import java.util.Properties; import net.gielinor.network.sql.impl.MySQLDonation; public class MySQLHandler extends Thread { private static final MySQLHandler mysqlHandler = new MySQLHandler(); public static MySQLHandler getMySQLHandler() { return mysqlHandler; } private static List<MySQLDatabase> updateList; private static String host; private static String database; private static String username; private static String password; @Override public void run() { while (true) { for (MySQLDatabase database : updateList) { try { if (database.getConnection() == null) { database.connect(); } else { database.ping(); } database.cycle(); } catch (Exception ex) { ex.printStackTrace(); } try { Thread.sleep(10000); } catch (Exception ex) { } } } } private static void loadProperties() { Properties p = new Properties(); try { p.load(new FileInputStream("./sql.ini")); host = p.getProperty("host"); database = p.getProperty("database"); username = p.getProperty("username"); password = p.getProperty("password"); } catch (Exception ex) { System.out.println("Error loading MySQL properties."); } } public static String getHost() { return host; } static { loadProperties(); updateList = new ArrayList<MySQLDatabase>(); updateList.add(new MySQLDonation(host, database, username, password)); } } 

MySQLDonation

 package net.gielinor.network.sql.impl; import java.sql.ResultSet; import java.sql.SQLException; import net.gielinor.game.model.player.Client; import net.gielinor.game.model.player.PlayerHandler; import net.gielinor.game.model.player.PlayerSave; import net.gielinor.network.sql.MySQLDatabase; public final class MySQLDonation extends MySQLDatabase { public MySQLDonation(String host, String database, String username, String password) { super(host, database, username, password); } @Override public void cycle() throws SQLException { ResultSet results = query("SELECT * FROM `gieli436_purchases`.`donations`"); if (results == null) { return; } while (results.next()) { String username = results.getString("username").replace("_", " "); System.out.println("name=" + username); Client client = (Client) PlayerHandler.getPlayer(username.toLowerCase()); System.out.println(client == null); if (client != null && !client.disconnected) { int creditamount = results.getInt("creditamount"); if (creditamount <= 0) { continue; } handleDonation(client, creditamount); query(String.format("DELETE FROM `gieli436_purchases`.`donations` WHERE `donations`.`username`='%s' LIMIT 1", client.playerName.replaceAll(" ", "_"))); } } } @Override public void ping() { super.ping("donations", "username"); } private void handleDonation(Client client, int creditamount) throws SQLException { client.credits = (client.credits + creditamount); client.sendMessage("Thank you for your purchase. You have received " + creditamount + " store credits."); PlayerSave.save(client); } } 

在这里发生exception:在MySQLDonation中的while循环中,实际的堆栈跟踪是这样的:

 java.sql.SQLException: Operation not allowed after ResultSet closed at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926) at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:794) at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:7077) at net.gielinor.network.sql.impl.MySQLDonation.cycle(Unknown Source) at net.gielinor.network.sql.MySQLHandler.run(Unknown Source) 

有了这些信息,我可以说这确实奏效,我得到了我的信息,而不是在游戏中,但它重复,就像用户从不被删除查询,所以它给了他们无限的奖励。 如果您需要更多信息,请随时询问。

当您运行Delete查询时,您使用Select查询中使用相同的Statement 。 当您在同一个Statement上重新执行时,以前的ResultSet被closures。

为了避免这种情况,每次执行查询时都应该创build一个新的Statement 。 所以删除statement = connection.createStatement();MySQLDatabase类的connect()方法中,并将该类中的所有statementreplace为connection.createStatement() 。 您也可以select完全删除私有variablesstatement

你可以在这里阅读更多。

当我们使用同一个语句对象作为diff时,这个错误有时会发生。 types

检查语句objectsss;