当前位置: 首页 > 面试题库 >

Java JDBC MySQL异常:“在ResultSet关闭后不允许进行操作”

柳轶
2023-03-14
问题内容

我已经为此工作了将近一天半,但似乎无法解决此错误。我不知道为什么ResultSet被关闭。也许有些人可以帮助我。

MySQL数据库:

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));
    }

}

MySQL捐赠

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);
    }

}

异常发生在这里:在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查询时,请使用与查询中相同StatementSelect查询。当您在同一位置重新执行时Statement,前一个ResultSet将关闭。

为了避免这种情况,您应该在Statement每次html" target="_blank">执行查询时创建一个新的。因此,statement = connection.createStatement();从类中的connect()方法中删除,并将MySQLDatabase该类中的所有内容替换statementconnection.createStatement()。您也可以选择statement完全删除私有变量。

您可以在此处了解更多信息。



 类似资料:
  • 问题内容: 我被错误卡住了,这里的第42行是,请帮我解决这个问题,我在这里待了几个小时。 这是我的代码: 问题答案: 一个对象只能具有一个active对象,因此在执行时,第一个ResultSet()被关闭。 创建两个对象,一个用于,另一个用于。 引用以下内容的javadoc : 默认情况下,每个对象只能同时打开一个对象。因此,如果一个对象的读取与另一个对象的读取是交错的,则每个对象必须已由不同的对

  • 问题内容: 我被错误卡住了,这里的第42行是,请帮我解决这个问题,我在这个问题上待了几个小时。 这是我的代码: 问题答案: 一个对象只能有一个active对象,因此在执行时,第一个ResultSet()被关闭。 创建两个对象,一个用于,另一个用于。 引用以下内容的javadoc : 默认情况下,每个对象只能同时打开一个对象。因此,如果一个对象的读取与另一对象的读取交错,则每个对象必须已由不同的对象

  • 问题内容: 我正在尝试执行getPendingSalesOrderIDs()方法,该方法调用方法selectInAsending(…)。 但这显示了一个SQLException,它说java.sql.SQLException:在ResultSet关闭后不允许进行该操作 此处db.endSelect()将关闭所有连接。 我认为问题就在于此。 问题答案: 如果关闭ResultSet,为什么不删除它(在

  • 我正在使用MySQL连接器获取URL以查找网页上的值。 我得到了上述信息,我不知道为什么。它插入来自rs1的第一条记录,但我不确定它为什么要关闭它。 下面是我的代码

  • 下面是相关的代码部分:Server. Proxy.update_allLogOut:(第65行是时括号) 服务器服务器: 主要: 我必须指出,它99%的运行时间都没有例外。。但有几次我遇到了这个例外,我不明白为什么会发生这种情况。有什么想法吗?很明显,有些地方做错了,但这里所有类似的主题都没有给出这个问题的答案。。。

  • 问题内容: 获取java.sql.SQLException:ResultSet关闭后不允许进行操作当我执行以下代码时,出现异常。我认为这是因为我正在与他相同的连接对象编写新语句。我应该如何重写它,以便可以创建准备好的语句并开始使用rs2?即使连接到相同的数据库,我也必须创建一个新的连接对象吗? 问题答案: 问题在于你在中获取数据的方式。每次访问你都会获得新鲜的食物,但你不会关闭它。 这违反了Sta