Как правильно обрабатывать sqlite запросы в разных потоках? - PullRequest
0 голосов
/ 05 мая 2018

Я работаю над приложением для iPhone, которое использует базу данных sqlite. Приложение загружает данные из Интернета в фоновом потоке с пользовательским интерфейсом в основном потоке. Поток фоновой загрузки может предварительно выполнить INSERT, UPDATE и SELECT в базе данных. Уровень пользовательского интерфейса также может взаимодействовать с базой данных, выполняя UPDATE и SELECT. Если я не сильно взаимодействую с пользовательским интерфейсом во время загрузки фонового потока, все работает нормально. Однако я начинаю сталкиваться с проблемами, когда во время загрузки выполняется много ОБНОВЛЕНИЙ в основном потоке (UI).

В каждом запросе к базе данных я использую оператор @synchronized, но это не решает проблему. Когда запросы (из пользовательского интерфейса и из фонового потока) выполняются в одно и то же время, это приводит к потере данных. Обновление данных в главном потоке работает также хорошо, как и в фоновом режиме (если они выполняются отдельно друг от друга).

База данных имеет sqlite3_threadsafe () == 2; Для всех запросов я использую одно соединение, может проблема в этом скрывается?

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

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

Если вы хотите читать и писать одновременно, рассмотрите возможность использования WAL mode .

0 голосов
/ 05 мая 2018

Согласно документам вам следует вызвать функцию sqlite3_config() и выбрать модель потоков. Я бы рекомендовал сначала попробовать SQLITE_CONFIG_SERIALIZED.

Также убедитесь, что вы не используете флаг SQLITE_OPEN_NOMUTEX для sqlite3_open_v2().

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...