在我的项目中,我使用嵌入式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;
}
我在程序开始时仅建立了一次连接,并在不重新连接的情况下将其用于进一步的连接(我从类中获取了静态对象 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;
}
}
如果我执行创建,读取,更新,插入表查询-一切都很好,但是当我尝试删除某些表时-我会收到错误消息:
SQLiteException: [SQLITE_LOCKED] A table in the database is locked (database table is locked)
我听说在没有关闭最后一个连接的情况下尝试连接数据库时会发生此错误。但是在整个程序执行过程中,我仅使用一次连接。 为什么会发生?怎么修?有什么想法吗?
提前谢谢。问候...
答案 0 :(得分:1)
之所以发生这种情况,是因为您使用的是一个连接而不是建立新的连接。为了删除表,您需要对该表具有排他锁。但是您无法在表上获得排他锁,因为先前的操作已经在表上具有共享锁。在关闭连接之前,先前的操作锁不会释放。 在这里要做的正确的事情是使用try with resources约定。即使抛出异常,此操作也会自动为您关闭连接。每次想要访问数据库时,都需要创建一个新的连接。因此,只需让您的connectable类每次都创建一个新的sql light连接器即可。然后,任务需要放在整个事物的可连接对象中。