语句关闭后不允许进行任何操作

use*_*683 5 java mysql mysql-error-1064

我在No operations allowed after statement closed.尝试将值插入数据库的 Java 代码中收到带有签名的异常。错误签名表示我的 Statement 对象已关闭,我正在尝试在我的代码中再次使用它,但我很难理解为什么会发生这种情况,因为我没有关闭代码中任何地方的任何连接。

这是Java代码。

public class DataBaseAccessUtils {

    private static String jdbcUrl = 
            AppConfig.findMap("BXRequestTracker").get("jdbcUrl").toString();
    private static Connection connection = null;
    private static Statement statement = null;

    public static void insertHostname(String hostname, String rid, String fleet, String locale)
    {
        locale.toUpperCase();
        String sql = "UPDATE " + locale + "REQUESTTRACKER SET " + fleet 
                + "='" + hostname + "' WHERE RID='" + rid + "'";
        try {
            statement.execute(sql);
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static Statement connectToDatabase() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(DataBaseAccessUtils.jdbcUrl);
            statement = connection.createStatement();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return statement;
    }
Run Code Online (Sandbox Code Playgroud)

我还观察到,当有单线程执行时不会出现错误,当多个线程尝试同时更新数据库时会出现错误。

Bra*_*raj 5

创建一个用于连接管理的实用程序类,以在整个应用程序中进行单点管理。

不要在DataSource每次需要新连接时加载。

示例代码:

public class ConnectionUtil {

    private DataSource dataSource;

    private static ConnectionUtil instance = new ConnectionUtil();

    private ConnectionUtil() {
        try {
            Context initContext = new InitialContext();
            dataSource = (DataSource) initContext.lookup("JNDI_LOOKUP_NAME");
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    public static ConnectionUtil getInstance() {
        return instance;
    }

    public Connection getConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        return connection;
    }

    public void close(Connection connection) throws SQLException {
        if (connection != null && !connection.isClosed()) {
            connection.close();
        }
        connection = null;
    }

}
Run Code Online (Sandbox Code Playgroud)

始终关闭连接并处理它 try-catch-finally

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = ConnectionUtil.getInstance().getConnection();

            ...
        } finally {
            if (rs != null) {
                rs.close();
            }
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                ConnectionUtil.getInstance().close(conn);
            }
        }
Run Code Online (Sandbox Code Playgroud)


key*_*ser 2

statement是静态的,因此它在实例(和线程)之间共享。一个线程可能在另一个线程关闭该对象后尝试使用该对象。

在线程之间共享数据库连接和语句通常不是一个好主意,因为 JDBC 不要求连接是线程安全的。