2012-02-05 8 views
1

У меня есть 2 процесса, которые подключаются к одной и той же БД. Первый используется для чтения из БД, а второй используется для записи в БД. Первый процесс отправляет процедуры записи для выполнения второго процесса через очередь сообщений в Linux.SQLite issue - DB заблокирован обход

Каждая инструкция SQL принимается в процессе подготовки, этапа, завершения процедуры; Если подготовка и шаг выполняются в цикле 10000 раз, пока это не будет выполнено (это позволило преодолеть проблемы с блокировкой БД).

Чтобы добавить таблицу я сделать следующую процедуру:

  1. первый процесс посылает запрос на второй процесс, чтобы добавить таблицу и вставить мусор в его строк в journal_mode = ВЫКЛ в режиме с помощью MSG-д ,

  2. тогда первый процесс проверяет существующую таблицу, чтобы он мог продолжить свой алгоритм. (Он проверяет в цикле с USleep команды между витками.)

Проблема заключается в том, что второй процесс застревает на этапе выполнения из «ПРАГМА journal_mode = OFF;» потому что он говорит, что БД заблокирована (здесь тоже я использую цикл из 10000 итераций с usleep, чтобы проверить 10000 раз, чтобы БД была бесплатной, как я уже упоминал ранее).

Когда я добавляю к первому процессу в цикле «проверка существующей таблицы», операция закрытия соединения, второй процесс в порядке. Но теперь, когда я добавляю таблицы и значения когда-нибудь, я получаю «обратный запрос запрошенного прерывания запроса» в инструкции шага.

Любая помощь от того, что происходит здесь?

+0

Возможно, ваш процесс хочет отключить journal_mode, пока другой процесс записывается в БД. Попробуйте сделать ROLLBACK перед выключением journal_mode. –

+0

Первый процесс не записывается в БД, имеет только соединение для чтения БД. Второй процесс - это тот, который отключает журнал_мод, а затем записывается в эту БД. –

+0

У вас есть какие-либо результирующие наборы/курсоры, открытые на стороне читателя, ожидая, когда запись произойдет? –

ответ

2

Используйте режим WAL. Он позволяет без проблем записывать один писатель и любое количество читателей. Вам не нужно проверять состояние блокировки и делать ретрансляции и т. Д.

Ограничение WAL: БД должна быть на локальном диске.

Производительность: крупные транзакции (1000 вставки или аналогичные) медленнее, чем классический журнал отката, но помимо этого скорость очень похожа, иногда даже лучше. Воспринимаемая производительность (пользовательский интерфейс, ожидающий завершения записи БД) значительно улучшается.

WAL - это новая технология, но уже используется в Firefox, телефонах Adroid и iOS и т. Д. Я тестировал 2 потока, работающих на полной скорости - один пишущий и другой - и не сталкивался с одной проблемой.

Возможно, вы сможете упростить свое приложение при использовании режима WAL.

+0

Я нахожу, что WAL быстро, как OFF. Я должен быть быстрой причиной в процедуре init, мне нужно собрать все таблицы, а во время выполнения обновить значения в них.Есть ли предложения по ускорению процедуры инициализации? Процедура init не должна быть стабильной в качестве процедуры выполнения, поэтому БД может быть подвержена риску. –

+0

Как насчет запуска (во время Init) без какого-либо журнала? Вы можете дополнительно использовать PRAGMA synchronous = 0 и locking_mode = EXCLUSIVE. Затем вы снова открываете БД со стандартными настройками и WAL. –

+0

Немного больше о параллелизме: я обнаружил одну странную проблему: когда connection1 открыл чтение (подготовленный оператор, который не был доработан), и после этого connection2 делает некоторую запись, тогда connection1 должен закрыть (завершить) чтение, чтобы иметь возможность написать. Звучит немного сложно, но общий урок прост: пока чтение и запись выполняются в отдельных соединениях, проблем с параллелизмом нет. –

Смежные вопросы