SQLite с оперативной памятью и изоляцией - PullRequest
0 голосов
/ 26 февраля 2020

Я хочу создать базу данных SQLite в памяти. Я хотел бы сделать два подключения к этой БД в памяти: одно для внесения изменений, а другое для чтения БД. Соединение модификатора откроет транзакцию и продолжит вносить изменения в базу данных до тех пор, пока не произойдет указанное событие c, после чего она совершит транзакцию. Другое соединение будет запускать запросы SELECT с чтением БД. Я не хочу, чтобы изменения, вносимые соединением модификатора, были видны соединению считывателя до тех пор, пока модификатор не зафиксировал (указанное событие произошло). Я хотел бы изолировать соединение читателя с соединением писателя.

Я пишу свое приложение на C ++. Я попытался открыть два соединения, как показано ниже:

int rc1 = sqlite3_open_v2("file:db1?mode=memory", pModifyDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_URI, NULL);
int rc2 = sqlite3_open_v2("file:db1?mode=memory", pReaderDb, SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_URI, NULL);

Я создал таблицу, добавил несколько строк и зафиксировал транзакцию в БД, используя 'pModifyDb'. Когда я пытаюсь получить значения, используя второе соединение pReaderDb, вызывая sqlite3_exe c (), я получаю код возврата 1 (SQLITE_ERROR).

Я попытался указать URI как "file:db1?mode=memory&cache=shared". Я не уверен, сохранит ли опция 'cache=shared' изоляцию. Но это также не сработало, когда соединение с устройством чтения пытается выполнить c запрос SELECT, код возврата был 6 (SQLITE_LOCKED). Может быть, потому, что опция общего кэша унифицировала оба соединения под капотом?

Если я уберу требование в памяти из URI, используя вместо этого "file:db1", все будет работать нормально. Я не хочу использовать файловую БД, поскольку мне требуется высокая пропускная способность, а размер БД не будет очень большим (~ 10 МБ).

Поэтому я хотел бы знать, как настроить две изолированные соединения с одной базой данных SQLite в памяти?

Заранее спасибо, kris

1 Ответ

0 голосов
/ 26 февраля 2020

Это невозможно с базой данных в памяти.

Вы должны использовать файл базы данных. Чтобы ускорить его, поместите его на RAM-диск (если это возможно) и отключите синхронную запись (PRAGMA synchronous=off) при каждом подключении.

Чтобы разрешить одновременное чтение и запись, необходимо переведите файл БД в режим WAL .

...