Как избежать ошибок блокировки SQLiteException
Я разрабатываю приложение для Android. Он имеет несколько потоков чтения и записи в базу данных Android SQLite. Я получаю следующую ошибку:
SQLiteException: код ошибки 5: база данных заблокирована
Я понимаю, что SQLite блокирует весь db при вставке/обновлении, но эти ошибки возникают только при вставке/обновлении, когда я запускаю запрос select. Запрос select возвращает курсор, который остается открытым довольно часто (несколько секунд несколько раз), в то время как я перебираю его. Если запрос выбора не запущен, я никогда не получаю блокировки. Я удивлен, что select может заблокировать db. Возможно ли это, или что-то еще происходит?
Какой лучший способ избежать таких блокировок?
Ответы
Ответ 1
Возможно, вы открываете и закрываете несколько соединений с базами данных в разных потоках. Это плохая идея. Просто откройте одно соединение с базой данных и повторите его повсеместно; SQLite будет гарантировать, что параллельные обращения будут правильно сериализованы.
Как и в случае с ответом jcwenger, использование ContentProvider - еще один способ достижения этого, но потребует гораздо более навязчивых изменений в вашем коде.
Ответ 2
Не оставляйте курсоры открытыми для "довольно долгого времени". Если вы можете позволить себе все свои данные в памяти сразу, сделайте это.
Если вы не можете, попробуйте увеличить тайм-аут занятости.
Ответ 3
Перенести на ContentProvider вместо прямого доступа к БД. ContentResolver устраняет все проблемы с потоками для вас, а также позволяет использовать другие полезные функции, такие как совместное использование данных между приложениями или синхронизация с сервером.
Накладные расходы api ContentResolver минимальны. Вам просто нужно определить строку AUTHORITY (уникальная строка, идентифицирующая "вид" ваших данных, - используйте строку типа "com.example.myapp.contacts" ) и используйте ContentResolver.bla, а не db.bla.
Ответ 4
Это вызвано функцией beginTransaction(). Посмотрите на свой код, проблема решена для моего приложения, чтобы создать линию комментариев этой строки (beginTransaction)