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