вопрос многопоточности блокировки базы данных sqlite - PullRequest
1 голос
/ 20 марта 2019

У меня проблема с «блокировкой базы данных», несмотря на то, что sqlite был скомпилирован с -DSQLITE_THREADSAFE = 2, и каждый поток использует свое собственное соединение с базой данных, как этот упрощенный код:

thread *t = new thread(RandomTextThread);
t.join();

и

    static void RandomTextThread(void * aArg)
{
    RandomText *rt1;

    rt1 = new RandomText();
    rt1->genRandomText();
}

и

    RandomText::RandomText() {

    int rc;

    //
    // open the database
    //

    rc = sqlite3_open("mydata.db.sqlite", &this->db);
}

Таким образом, в каждом потоке, созданном статической функцией RandomTextThread, будет создан новый объект RandomText, который, в свою очередь, создаст новое соединение sqlite, хранящееся в переменной класса -> db.

Иногда код будет выполнять команды DML. И это работает для одного потока без ошибок. Но два или более потоков, созданных с помощью механизма, описанного выше, завершаются сбоем до тех пор, пока потоки не выполнят параллельный DML.

Система старая, я мог бы скомпилировать sqlite 3.27, но я могу использовать только GCC 4.2 с решением TinyThread ++, которое, в свою очередь, использует POSIX pthread.h. Любую помощь оцените.

1 Ответ

0 голосов
/ 26 марта 2019

SQLITE_BUSY - ожидаемый код ошибки, когда база данных одновременно читается и изменяется. Используя Запись с записью в очередь , возможно, значительно уменьшится количество случаев, если есть только один писатель и много читателей.

sqlite3_exec может сохранять блокировку после завершения, если вы отключили режим автоматической фиксации, например, с помощью команды BEGIN. В этом случае вы должны выполнить команду COMMIT или ROLLBACK, чтобы снять блокировку.

Вы можете использовать sqlite3_busy_timeout для установки обработчика покупок, который выполняет ожидание внутри самого SQLite.

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