Таблица базы данных заблокирована (Java, SQLite) - PullRequest
0 голосов
/ 20 мая 2019

В моем проекте я использую встроенную базу данных 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;
    }

Я устанавливаю соединение только один раз в начале программы и использую его в дальнейшем без повторного соединения (я беру статический объект соединение изкласс).

И я выполняю запросы к базе данных со следующим кодом:

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)  

Я слышал, что эта ошибка возникает при попытке подключения к базе данных, когда последнее соединение не было закрыто.Но я использую только один раз соединение во время исполнения программы.Почему так происходит?Как исправить?Есть идеи?

Заранее спасибо.С уважением ...

1 Ответ

1 голос
/ 20 мая 2019

Это происходит потому, что вы используете одно соединение вместо создания новых.Для того, чтобы удалить таблицу, вам нужен эксклюзивный замок на столе.Но вы не можете получить эксклюзивную блокировку таблицы, потому что ваша предыдущая операция уже имеет общую блокировку таблицы.Блокировки предыдущих операций не снимаются, пока вы не закроете соединение.Правильнее всего здесь использовать соглашение try with resources.Это автоматически закроет соединение для вас, даже если возникнет исключение.Вам нужно создавать новое соединение каждый раз, когда вы хотите перейти к базе данных.Так что просто сделайте так, чтобы ваш подключаемый класс каждый раз создавал новый световой соединитель sql.Тогда задача должна быть в Connectable, окружающем все это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...