0

我正在开发一个简单的 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() 方法时,我得到一个异常说“数据库表被锁定”。我猜这是由于可能在 hasTable() 方法中调用的非关闭 SELECT 语句。据我所知,即使在运行检索查询时数据库表也被锁定,因此在其他人尝试选择数据时无法更新表。但是如何解决这个问题,我不确定。有任何想法吗?

4

1 回答 1

1

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

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

If you absolutely want to use jdbc directly, the best practice is still to close the connection after usage. If you prefer for obscure reasons to keep your read connection alive i would advise to use 2 different users, one granted with read only access and another one for update whose connections should be systematically closed after each call. In all case you must take care of properly release connection and eventual prepared statements after usage or you will experiment dead locks and / or memory leaks.

cf. http://javarevisited.blogspot.fr/2012/08/top-10-jdbc-best-practices-for-java.html

于 2013-03-04T17:04:25.823 回答