mysql jdbc java.sql.sqlexception:结果集关闭后不允许操作

oyxsuwqo  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(487)

我有一个使用不同的jdbc驱动程序查询数据库的程序。此错误特定于mysql驱动程序。
这是基本情况。
我有另一个查询运行器类,它使用了一个postgresqljdbc驱动程序,工作正常。注意线路conn.close();这在我的postgresql查询运行程序上运行得很好,但是对于这个sql运行程序,它会出现错误。
我已拆下连接线close();这段代码运行良好,但随着时间的推移,它会在数据库中累积休眠连接。我怎样才能解决这个问题?
newrelic是一个第三方应用程序,我正在向它提供数据,如果您不知道它是什么,请不要担心它与此错误不太相关。
主要类别

public class JavaPlugin {
public static void main(String[] args) {
    try {
        Runner runner = new Runner();
        runner.add(new MonitorAgentFactory());
        runner.setupAndRun(); // never returns
    }
    catch (ConfigurationException e) {
        System.err.println("ERROR: " + e.getMessage());
        System.exit(-1);
    }
    catch (Exception e) {
        System.err.println("ERROR: " + e.getMessage());
        System.exit(-1);
        }
    }
}

mysql查询运行程序类

import com.newrelic.metrics.publish.util.Logger;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.sql.Statement;

public class MySQLQueryRunner {
    private static final Logger logger = Logger.getLogger(MySQLQueryRunner.class);
    private String connectionStr;
    private String username;
    private String password;

    public MySQLQueryRunner(String host, long port, String database, String username, String password) {
        this.connectionStr = "jdbc:mysql://" + host + ":" + port + "/" + database + "?useSSL=false";
        this.username = username;
        this.password = password;
    }

    private void logError(String message) {
        logger.error(new Object[]{message});
    }

    private void logDebugger(String message) {
        logger.debug(new Object[]{message});
    }

    private Connection establishConnection() {
        try {
            Class.forName("com.mysql.jdbc.Driver");

        } catch (ClassNotFoundException e) {
            logError("MySQL Driver could not be found");
            e.printStackTrace();
            return null;
        }
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(connectionStr, username, password);
            logDebugger("Connection established: " + connectionStr + " using " + username);
        } catch (SQLException e) {
            logError("Connection Failed! Check output console");
            e.printStackTrace();
            return null;
        }
        return connection;
    }

    public ResultSet run(String query) {
        Connection conn = establishConnection();
        if (conn == null) {
            logError("Connection could not be established");
            return null;
        }
        try {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            conn.close();
            return rs;
        } catch (SQLException e) {
            logError("Failed to collect data from database");
            e.printStackTrace();
            return null;
        }

    }
}

代理类

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import com.newrelic.metrics.publish.Agent;

public class LocalAgent extends Agent {
    private MySQLQueryRunner queryRunner;
    private String name;
    private Map<String, Object> thresholds;
    private int intervalDuration;
    private int intervalCount;

    public LocalAgent(String name, String host, long port, String database, String username, String password, Map<String, Object> thresholds, int intervalDuration) {
        super("com.mbt.local", "1.0.0");
        this.name = name;
        this.queryRunner = new MySQLQueryRunner(host, port, database, username, password);
        // this.eventPusher = new NewRelicEvent();
        this.thresholds = thresholds;
        this.intervalDuration = intervalDuration;
        this.intervalCount = 0;
    }

    /**
     * Description of query
     */
    private void eventTestOne() {
        String query = "select count(1) as jerky from information_schema.tables;";
        ResultSet rs = queryRunner.run(query);
        try {
            while (rs.next()) {
                NewRelicEvent event = new NewRelicEvent("localTestOne");
                event.add("jerky", rs.getInt("jerky"));
                event.push();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * blah
     */
    private void eventTestTwo() {
        String query = "SELECT maxlen FROM information_schema.CHARACTER_SETS;";
        ResultSet rs = queryRunner.run(query);
        try {
            while (rs.next()) {
                NewRelicEvent event = new NewRelicEvent("localTestTwo");
                event.add("beef", rs.getString("maxlen"));
                event.push();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void pollCycle() {
        if (this.intervalCount % this.intervalDuration == 0) {
            eventTestOne();
            eventTestTwo();
        this.intervalCount = 0;
        }
        // Always incrementing intervalCount, keeping track of poll cycles that have passed
        this.intervalCount++;
    }

    @Override
    public String getAgentName() {
        return this.name;
    }
}
eanckbw9

eanckbw91#

问题是您正在尝试访问 ResultSet 之后 connection 已关闭。
您应该在调用的方法中打开和关闭连接 run() 这样,当您访问并通过 Resultset 把它关上 finally 调用方法的块。
如果你能在 ResultSetrun() 方法并将数据添加到 object 并归还 object ,这样您就可以在 finallyrun() 方法。

相关问题