Разработчик никогда не должен тестировать свое собственное программное обеспечение
Разработка и тестирование - это две диаметрально противоположные дисциплины. Разработка - это все о строительстве, а тестирование - о сносе. Эффективное тестирование требует особого подхода и подхода, при котором вы пытаетесь выявить ошибки разработчика, найти дыры в их предположениях и недостатки в их логике. Большинство людей, включая меня, просто не в состоянии подвергнуть себя и свой собственный код такому тщательному анализу и все еще остаются объективными.
Во-первых, избегайте одновременного доступа к файлам базы данных sqlite. Параллелизм - одно из слабых мест sqlite, и если у вас много параллельного приложения, рассмотрите возможность использования другого механизма базы данных.
Если вы не можете избежать параллелизма или удалить sqlite, заключите свои транзакции write в BEGIN IMMEDIATE ;
... КОНЕЦ;
. Режим транзакции по умолчанию в sqlite - DEFERRED
, что означает, что блокировка устанавливается только при первой реальной попытке записи. С транзакциями IMMEDIATE
блокировка устанавливается немедленно, или вы сразу получаете SQLITE_BUSY
. Когда кто-то удерживает блокировку базы данных, другие попытки блокировки приведут к SQLITE_BUSY
.
Работа с SQLITE_BUSY
- это то, что вы должны решить сами. Для многих приложений ожидание в течение секунды или двух, а затем повторная попытка работает вполне нормально, и они прекращаются после n
неудачных попыток. Есть помощники API sqlite3, которые упрощают эту задачу, например sqlite3_busy_handler ()
и sqlite3_busy_timeout ()
, но это также можно сделать вручную.
Вы также можете использовать синхронизацию уровня ОС для получить блокировку мьютекса для базы данных или использовать межпоточный / межпроцессный обмен сообщениями на уровне ОС, чтобы сигнализировать, когда один поток завершил доступ к базе данных.
Любой примитив SQLite вернет SQLITE_BUSY, если он попытается получить доступ к базе данных, к которой в это же время обращается другой процесс. Вы можете проверить этот код ошибки и просто повторить действие.
В качестве альтернативы вы можете использовать синхронизацию ОС - мьютекс в MS Windows или что-то подобное в других ОС. Процесс будет пытаться получить мьютекс, и если кто-то уже владеет им, процесс будет заблокирован до тех пор, пока другой процесс не завершит операцию и не освободит мьютекс. Следует проявлять осторожность, чтобы не допустить случаев, когда процесс получает мьютекст и никогда не освобождает его.
Обычно вам нужно обернуть ваш код доступа к данным транзакциями. Это обеспечит единообразие ваших данных. Больше ничего не требуется.
В SQLite вы используете пары
BEGIN TRANSACTION
COMMIT TRANSACTION
для разграничения транзакций. Поместите свой код SQL между ними, чтобы он выполнялся в одной транзакции.
Однако, как предыдущие люди прокомментировали до меня, вам нужно уделять пристальное внимание проблемам параллелизма. SQLite может работать достаточно быстро, если он используется для чтения (несколько считывателей не блокируются и могут работать одновременно).
Однако картина значительно меняется, если ваш код чередует доступ для записи и чтения. С SQLite - весь ваш файл базы данных будет заблокирован, если активен хотя бы один писатель.