我正在开发一个简单的 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 语句造成的。据我所知,即使运行检索查询,数据库表也会被锁定,以便在其他人尝试选择数据时无法更新表。但如何解决这个问题,我不确定。有什么想法吗?
最佳答案
我不知道您的环境是什么,但您应该使用带有连接池的数据源,并检索和关闭每个事务的连接。
完美的方法可能是使用容器( Spring 或 Java EE 之一)并让他为您管理事务,这样您就不会介意正确管理 JDBC 资源。您还可以指定是否允许更新当前事务并管理其他事务属性,例如隔离。
如果您绝对想直接使用jdbc,最佳实践仍然是在使用后关闭连接。如果您出于不明原因更喜欢保持读取连接处于 Activity 状态,我建议使用 2 个不同的用户,一个被授予只读访问权限,另一个用于更新,其连接应在每次调用后系统地关闭。
在所有情况下,您都必须在使用后正确释放连接和最终准备好的语句,否则您将尝试死锁和/或内存泄漏。
比照。 http://javarevisited.blogspot.fr/2012/08/top-10-jdbc-best-practices-for-java.html
关于java - JDBC "database table is locked"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15205825/