SQLite3 и несколько процессов

Разработчик никогда не должен тестировать свое собственное программное обеспечение

Разработка и тестирование - это две диаметрально противоположные дисциплины. Разработка - это все о строительстве, а тестирование - о сносе. Эффективное тестирование требует особого подхода и подхода, при котором вы пытаетесь выявить ошибки разработчика, найти дыры в их предположениях и недостатки в их логике. Большинство людей, включая меня, просто не в состоянии подвергнуть себя и свой собственный код такому тщательному анализу и все еще остаются объективными.

19
задан Esoteric Screen Name 31 May 2013 в 14:21
поделиться

4 ответа

Во-первых, избегайте одновременного доступа к файлам базы данных sqlite. Параллелизм - одно из слабых мест sqlite, и если у вас много параллельного приложения, рассмотрите возможность использования другого механизма базы данных.

Если вы не можете избежать параллелизма или удалить sqlite, заключите свои транзакции write в BEGIN IMMEDIATE ; ... КОНЕЦ; . Режим транзакции по умолчанию в sqlite - DEFERRED , что означает, что блокировка устанавливается только при первой реальной попытке записи. С транзакциями IMMEDIATE блокировка устанавливается немедленно, или вы сразу получаете SQLITE_BUSY . Когда кто-то удерживает блокировку базы данных, другие попытки блокировки приведут к SQLITE_BUSY .

Работа с SQLITE_BUSY - это то, что вы должны решить сами. Для многих приложений ожидание в течение секунды или двух, а затем повторная попытка работает вполне нормально, и они прекращаются после n неудачных попыток. Есть помощники API sqlite3, которые упрощают эту задачу, например sqlite3_busy_handler () и sqlite3_busy_timeout () , но это также можно сделать вручную.

Вы также можете использовать синхронизацию уровня ОС для получить блокировку мьютекса для базы данных или использовать межпоточный / межпроцессный обмен сообщениями на уровне ОС, чтобы сигнализировать, когда один поток завершил доступ к базе данных.

16
ответ дан 30 November 2019 в 04:48
поделиться

Любой примитив SQLite вернет SQLITE_BUSY, если он попытается получить доступ к базе данных, к которой в это же время обращается другой процесс. Вы можете проверить этот код ошибки и просто повторить действие.

В качестве альтернативы вы можете использовать синхронизацию ОС - мьютекс в MS Windows или что-то подобное в других ОС. Процесс будет пытаться получить мьютекс, и если кто-то уже владеет им, процесс будет заблокирован до тех пор, пока другой процесс не завершит операцию и не освободит мьютекс. Следует проявлять осторожность, чтобы не допустить случаев, когда процесс получает мьютекст и никогда не освобождает его.

2
ответ дан 30 November 2019 в 04:48
поделиться

SQLite FAQ именно по этому

0
ответ дан 30 November 2019 в 04:48
поделиться

Обычно вам нужно обернуть ваш код доступа к данным транзакциями. Это обеспечит единообразие ваших данных. Больше ничего не требуется.

В SQLite вы используете пары

BEGIN TRANSACTION

COMMIT TRANSACTION

для разграничения транзакций. Поместите свой код SQL между ними, чтобы он выполнялся в одной транзакции.

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

Однако картина значительно меняется, если ваш код чередует доступ для записи и чтения. С SQLite - весь ваш файл базы данных будет заблокирован, если активен хотя бы один писатель.

2
ответ дан 30 November 2019 в 04:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: