Блокировка и блокировка базы данных Android


Answers

В конце концов мы использовали ContentProvider . Это, похоже, прояснило проблемы.

Question

Мы используем AsyncTasks для доступа к таблицам баз данных и курсорам.

К сожалению, мы наблюдаем случайные исключения в отношении блокировки базы данных.

E/SQLiteOpenHelper(15963): Couldn't open iviewnews.db for writing (will try read-only):
E/SQLiteOpenHelper(15963): android.database.sqlite.SQLiteException: database is locked
E/SQLiteOpenHelper(15963):  at     android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
E/SQLiteOpenHelper(15963):  at     android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1637)
E/SQLiteOpenHelper(15963):  at     android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1587)
E/SQLiteOpenHelper(15963):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:638)
E/SQLiteOpenHelper(15963):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:659)
E/SQLiteOpenHelper(15963):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:652)
E/SQLiteOpenHelper(15963):  at android.app.ApplicationContext.openOrCreateDatabase(ApplicationContext.java:482)
E/SQLiteOpenHelper(15963):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:193)
E/SQLiteOpenHelper(15963):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
E/SQLiteOpenHelper(15963):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)
E/SQLiteOpenHelper(15963):  at com.iview.android.widget.IViewNewsTopStoryWidget.initData(IViewNewsTopStoryWidget.java:73)
E/SQLiteOpenHelper(15963):  at com.iview.android.widget.IViewNewsTopStoryWidget.updateNewsWidgets(IViewNewsTopStoryWidget.java:121)
E/SQLiteOpenHelper(15963):  at com.iview.android.async.GetNewsTask.doInBackground(GetNewsTask.java:338)
E/SQLiteOpenHelper(15963):  at com.iview.android.async.GetNewsTask.doInBackground(GetNewsTask.java:1)
E/SQLiteOpenHelper(15963):  at android.os.AsyncTask$2.call(AsyncTask.java:185)
E/SQLiteOpenHelper(15963):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
E/SQLiteOpenHelper(15963):  at java.util.concurrent.FutureTask.run(FutureTask.java:122)
E/SQLiteOpenHelper(15963):  at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
E/SQLiteOpenHelper(15963):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
E/SQLiteOpenHelper(15963):  at java.lang.Thread.run(Thread.java:1060)

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

Одно из предложений, которое у меня было, - использовать ContentProvider , поскольку это будет обрабатывать доступ к базе данных из нескольких потоков. Я собираюсь посмотреть на это, но является ли это рекомендуемым методом решения такой проблемы? Это кажется довольно тяжеловесным, потому что мы говорим о фронте или сзади.




Вы должны вызывать getWritableDatabase() из функции, а не конструктора класса-помощника db. Если объект класса-помощника db создается с помощью SQLiteDatabase.openOrCreateDatabase(DB_PATH, null); или аналогичный, а затем getWritableDatabase() вызывается из функции, он попытается сделать синхронный вызов БД, вызывающий исключение блокировки БД.




Учтите, что базы данных SQLite основаны на файлах и не предназначены для доступа к многопроцессорному способу. Лучшая процедура смешивания SQLite с многопроцессорной обработкой заключается в использовании семафоров (aquire (), release ()) в каждом доступе, связанном с базой данных.

Если вы создаете оболочку Db, которая использует / освобождает глобальный семафор, ваш доступ к БД будет потокобезопасным. На самом деле это означает, что вы можете получить загрузочное окно, потому что вы в очереди на доступ к БД. Таким образом, вы можете только обернуть доступ с помощью семафоров, если это операция, которая изменяет базу данных, поэтому, пока вы изменяете db, никто не сможет получить к ней доступ и дождитесь завершения процесса записи.






Links