数据库 table 已锁定(Java,SQLite)
Database table is locked (Java, SQLite)
在我的项目中,我使用了嵌入式SQLite 数据库。我使用以下代码进行连接:
public class SQLiteConnector {
private final String TAG = "SQLiteConnector";
public static final String CONFIG_PACKAGE = "configs";
public static final String DATABASE_NAME = "user_config.db";
private String packagePath;
private String databasePath;
private static Connection connection;
public boolean connect() {
boolean isConncted = true;
if(connection == null){
FutureTask<Boolean> task = new FutureTask<>(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
System.out.println("NEW CONNECTION...");
String url = "jdbc:sqlite:" + databasePath;
SQLiteDataSource sqliteDataSource = new SQLiteDataSource();
sqliteDataSource.setUrl(url);
try {
connection = sqliteDataSource.getConnection();
} catch (SQLException ex) {
Logger.getLogger(SQLiteConnector.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
return true;
}
});
Thread connectThread = new Thread(task);
connectThread.setName("DBConnectionThread");
connectThread.start();
try {
isConncted = task.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(SQLiteConnector.class.getName()).log(Level.SEVERE, null, ex);
}
}
return isConncted;
}
public Connection getConnection(){
return connection;
}
我只在程序开始时建立一次连接并在以后使用它而无需重新连接(我从 class 中获取静态对象 connection)。
我正在使用以下代码执行数据库查询:
public abstract class Requestable {
public static synchronized ResultSet execute(String query){
ResultSet resultSet = null;
SQLiteConnector connector = new SQLiteConnector();
Connection connection = connector.getConnection();
try {
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.execute();
resultSet = preparedStatement.getResultSet();
} catch (SQLException ex) {
Logger.getLogger(Requestable.class.getName()).log(Level.SEVERE, null, ex);
}
return resultSet;
}
}
如果我执行创建、读取、更新、插入 table 查询 - 一切都很好,但是当我尝试删除一些 table - 我得到一个错误:
SQLiteException: [SQLITE_LOCKED] A table in the database is locked (database table is locked)
我听说在最后一个连接未关闭的情况下尝试连接到数据库时会发生此错误。但是我在整个程序执行过程中只使用一次连接。
为什么会这样?怎么修?有什么想法吗?
提前致谢。问候...
发生这种情况是因为您正在使用一个连接而不是建立新连接。为了删除 table,您需要对 table 进行独占锁定。但是您无法获得 table 上的排他锁,因为您之前的操作已经在 table 上获得了共享锁。在您关闭连接之前,之前的操作锁不会释放。
此处正确的做法是使用 try with resources 约定。这将自动为您关闭连接,即使抛出异常也是如此。每次要访问数据库时都需要创建一个新连接。因此,只需让您的 connectable class 每次创建一个新的 sql 灯连接器即可。然后任务需要在 Connectable 周围。
在我的项目中,我使用了嵌入式SQLite 数据库。我使用以下代码进行连接:
public class SQLiteConnector {
private final String TAG = "SQLiteConnector";
public static final String CONFIG_PACKAGE = "configs";
public static final String DATABASE_NAME = "user_config.db";
private String packagePath;
private String databasePath;
private static Connection connection;
public boolean connect() {
boolean isConncted = true;
if(connection == null){
FutureTask<Boolean> task = new FutureTask<>(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
System.out.println("NEW CONNECTION...");
String url = "jdbc:sqlite:" + databasePath;
SQLiteDataSource sqliteDataSource = new SQLiteDataSource();
sqliteDataSource.setUrl(url);
try {
connection = sqliteDataSource.getConnection();
} catch (SQLException ex) {
Logger.getLogger(SQLiteConnector.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
return true;
}
});
Thread connectThread = new Thread(task);
connectThread.setName("DBConnectionThread");
connectThread.start();
try {
isConncted = task.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(SQLiteConnector.class.getName()).log(Level.SEVERE, null, ex);
}
}
return isConncted;
}
public Connection getConnection(){
return connection;
}
我只在程序开始时建立一次连接并在以后使用它而无需重新连接(我从 class 中获取静态对象 connection)。
我正在使用以下代码执行数据库查询:
public abstract class Requestable {
public static synchronized ResultSet execute(String query){
ResultSet resultSet = null;
SQLiteConnector connector = new SQLiteConnector();
Connection connection = connector.getConnection();
try {
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.execute();
resultSet = preparedStatement.getResultSet();
} catch (SQLException ex) {
Logger.getLogger(Requestable.class.getName()).log(Level.SEVERE, null, ex);
}
return resultSet;
}
}
如果我执行创建、读取、更新、插入 table 查询 - 一切都很好,但是当我尝试删除一些 table - 我得到一个错误:
SQLiteException: [SQLITE_LOCKED] A table in the database is locked (database table is locked)
我听说在最后一个连接未关闭的情况下尝试连接到数据库时会发生此错误。但是我在整个程序执行过程中只使用一次连接。 为什么会这样?怎么修?有什么想法吗?
提前致谢。问候...
发生这种情况是因为您正在使用一个连接而不是建立新连接。为了删除 table,您需要对 table 进行独占锁定。但是您无法获得 table 上的排他锁,因为您之前的操作已经在 table 上获得了共享锁。在您关闭连接之前,之前的操作锁不会释放。 此处正确的做法是使用 try with resources 约定。这将自动为您关闭连接,即使抛出异常也是如此。每次要访问数据库时都需要创建一个新连接。因此,只需让您的 connectable class 每次创建一个新的 sql 灯连接器即可。然后任务需要在 Connectable 周围。