LINUX.ORG.RU

Как бороться с «database is locked» в sqlite?

 , , , ,


0

1

Есть sqlite БД с множественными подключениями (один поток - одно подключение). Но при активном использовании часто вылетает ошибка

database is locked Unable to fetch row

при попытке insert'а. Пробовал ставить

PRAGMA journal_mode=WAL;
не помогло.

Проблема в том, что в соседнем потоке может выполняться select по этой же таблице. Insert'ы разделены по потокам - insert в одну таблицу может выполняться только в одном потоке.

★★

Неужели только мьютексы?

SaBo ★★
() автор топика

Это однопользовательская база по сути. Делай через семафоры и т.д.. Текущий вариант в конце концов это к ним же и приведет.

anonymous
()
Ответ на: комментарий от anonymous

10 секунд ставил... Не помогло.

SaBo ★★
() автор топика
Ответ на: комментарий от anonymous

Ну посмотри FAQ, там черным по белому «threads are evil».

lu4nik ★★★
()

Да, это SQLite. Запись блочит базу, это поведение by design. Тут можно оставить один поток, который будет писать в базу, а остальные потоки будут ему сливать данные. Либо заняться поисками другой БД, которая нормально поддерживает многопоточность.

hippi90 ★★★★★
()
Ответ на: комментарий от hippi90

Я попробовал сделать через мьютексы на момент выполнения запроса. Но ошибка осталась. Судя по всему, надо ставить мьютекс ещё до вызова prepare.

SaBo ★★
() автор топика
Ответ на: комментарий от SaBo

Бред какой-то...

QSqlQuery ThreadDb::query() {
    exec_mutex.lock();
    return QSqlQuery(database());
}

bool ThreadDb::exec(QSqlQuery &query) {
    int result = query.exec();
    exec_mutex.unlock();
    return result;
}

QSqlQuery ThreadDb::exec(const QString &query) {
    QSqlQuery result = database().exec(query);
    exec_mutex.unlock();
    return result;
}

bool ThreadDb::exec(QSqlQuery &query, const QString& sql) {
    int result = query.exec(sql);
    exec_mutex.unlock();
    return result;
}

Все запросы начинаются с вызова ThreadDb::query() и заканчиваются одним из ThreadDb::exec(). Всё равно ошибка «database is locked Unable to fetch row»

SaBo ★★
() автор топика
Ответ на: комментарий от SaBo

А, ну да... Я тормоз.

exec'ом же жизнь не заканчивается.

SaBo ★★
() автор топика

sqlite можно, если хочется, использовать из нескольких потоков/процессов. Синхронизация, если память не изменяет, на уровне транзакций.

invy ★★★★★
()

use open readonly

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.