2010-03-07 3 views
16

Я разрабатываю приложение для Android. Он имеет несколько потоков чтения и записи в базу данных Android SQLite. Я получаю следующее сообщение об ошибке:Как избежать ошибок блокировки SQLiteException

SQLiteException: error code 5: database is locked

Я понимаю, что SQLite блокирует весь дб на вставке/обновлении, но эти ошибки, как представляется только произойдет при установке/обновления в то время как я бегаю запрос на выборку. Запрос select возвращает курсор, который остается открытым довольно часто (несколько секунд несколько раз), в то время как я перебираю его. Если запрос выбора не запущен, я никогда не получаю блокировки. Я удивлен, что select может заблокировать db. Возможно ли это, или что-то еще происходит?

Каков наилучший способ избежать таких замков?

+0

Вы говорите, оставив курсор открытым на некоторое время. Я считаю, что у меня такая же проблема, но мои курсоры поддерживаются listView. Вы когда-нибудь могли это исправить? – taer

+1

Да, я исправил это, сразу прочитав содержимое курсора в коллекции, закрою курсор, а затем повторюсь по коллекции, чтобы выполнить трудоемкую работу. Если вы используете listView, вы должны сделать то же самое и использовать ArrayAdapter или написать собственный адаптер, расширяющий ArrayAdapter. – TheArchedOne

+0

http://stackoverflow.com/questions/7657223/sqlite-exception-database-is-locked-issue/9503044#9503044 – junto

ответ

2

Не оставляйте курсоры открытыми для «довольно долгого времени». Если вы можете позволить себе все свои данные в памяти сразу, сделайте это.

Если вы не можете, попробуйте увеличить таймаут занятости.

1

Переход к ContentProvider вместо прямого доступа к БД. ContentResolver устраняет все проблемы с потоками для вас, а также позволяет использовать другие полезные функции, такие как совместное использование данных между приложениями или синхронизация с сервером.

Недостаток api в ContentResolver минимален. Вам просто нужно определить строку AUTHORITY (уникальная строка, идентифицирующая «вид» ваших данных, - используйте строку типа «com.example.myapp.contacts») и используйте ContentResolver.bla, а не db.bla.

7

Возможно, вы открываете и закрываете несколько соединений с базами данных в разных потоках. Это плохая идея. Просто откройте одно соединение с базой данных и повторите его повсеместно; SQLite будет гарантировать, что параллельные обращения сериализованы правильно.

Как и в случае с ответом jcwenger, использование ContentProvider является еще одним способом достижения этого, но потребует гораздо более навязчивых изменений в вашем коде.

+0

Я не открываю и не закрываю базу данных несколько раз, хотя я получаю эту ошибку, пожалуйста, возьмите [ссылка здесь] (http://stackoverflow.com/questions/13859840/application-crashes-on-installation-with-error-sqlite3-exec-failed-to-set-sync) – MobileEvangelist

0

Его вызвано BeginTransaction() function.Look в вашем коде, проблема решена для моего приложения, чтобы сделать строку комментария этой функции (BeginTransaction) линией

Смежные вопросы