Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JDBC“;“数据库表已锁定”;错误_Java_Sqlite_Jdbc_Locking - Fatal编程技术网

Java JDBC“;“数据库表已锁定”;错误

Java JDBC“;“数据库表已锁定”;错误,java,sqlite,jdbc,locking,Java,Sqlite,Jdbc,Locking,我正在开发一个简单的Java库,它将提供数据库访问。目前我正在研究访问SQLite。我有一个名为SQlite.java的类,它只实现实例方法。以下是一些方法的实现: public ResultSet retrieve(String query) { try { if (this.connection != null) { this.statement = this.connection.createStatement();

我正在开发一个简单的Java库,它将提供数据库访问。目前我正在研究访问SQLite。我有一个名为SQlite.java的类,它只实现实例方法。以下是一些方法的实现:

public ResultSet retrieve(String query) {
    try {
        if (this.connection != null) {
            this.statement = this.connection.createStatement();
            return this.statement.executeQuery(query);
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
    return null;
}

public ResultSet listTables() {
    try {
        return this.retrieve("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name");
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
    return null;
}

public boolean hasTable(String tableName) {
    try {
        ResultSet rs = this.listTables();
        while (rs.next()) {
            if (rs.getString(1).equals(tableName)) {
                return true;
            }
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
    return false;
}

public void update(String query) {
    try {
        if (this.connection != null) {
            this.statement = this.connection.createStatement();
            this.statement.executeUpdate(query);
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
}

public void dropTable(String tableName) {
    try {
        if (this.hasTable(tableName)) {
            this.update("DROP TABLE " + tableName); // TEST!
        } else {
            System.err.println("[ERROR] Table '" + tableName + "' not found!");
        }
    } catch (Exception e) {
        System.err.println("[ERROR] " + e.getMessage());
    }
}

当我测试dropTable()方法时,我得到一个异常,说“database table is locked”。我猜这是由于hasTable()方法中可能调用了一个非封闭的SELECT语句。据我所知,即使在运行检索查询时,数据库表也会被锁定,以便在其他人尝试选择数据时无法更新表。但如何解决这个问题,我不能确定。有什么想法吗?

我不知道您的环境是什么,但您应该使用带有连接池的数据源,并为每个事务检索和关闭连接。

完美的方法可能是使用容器(Spring或Java EE),让他为您管理事务,这样您就不会介意正确管理JDBC资源。您还可以指定是否允许更新当前事务,并管理其他事务属性,如隔离。

如果您绝对希望直接使用jdbc,最佳做法仍然是在使用后关闭连接。如果您出于模糊的原因希望保持您的读取连接处于活动状态,我建议使用两个不同的用户,一个被授予只读访问权限,另一个被授予更新权限,在每次调用后,其连接应系统地关闭。 在任何情况下,您都必须在使用后妥善释放连接和最终准备好的语句,否则您将试验死锁和/或内存泄漏


cf.

我实际上正在研究Hibernate。但是如果我直接使用JDBC,我是否必须使用静态方法(它将打开到数据库的连接,运行给定的查询,然后关闭连接)?目前,我正在使用一个带有java.sql.Connection实例变量的对象类,它并没有真正关闭。您可以让连接打开并在所有对话中重复使用它,但必须在对话结束时将其关闭。通过在每次使用后关闭它来确保资源的释放更容易,否则使用像spring这样的容器来委托作业。我只是让连接保持打开状态,因为我认为打开和关闭每个事务的连接都会导致开销。我将再次应用资源管理和测试。非常感谢。@temelm:是的,打开和关闭连接池确实会降低性能,但这就是连接池的作用:它将成本降低到几乎为零。