У меня есть соединение с базой данных только для чтения. Иногда при чтении данных из базы данных с запросом SELECT
он выдает SQLiteReadOnlyDatabaseException
.
Я открываю соединение следующим образом:
return SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
Запрос:
Select * FROM BudgetVersions WHERE entityId = ?
Я прочитал данные из базы данных с помощью db.rawQuery()
, например:
String query = ...;
Cursor c = db.rawQuery(query, new String[]{ activeBudgetId });
try {
if (c.moveToFirst()) {
bv.versionName = c.getString(c.getColumnIndexOrThrow("versionName"));
return bv;
} else {
return null;
}
} finally {
c.close();
}
Редко, я получаю такой крах, внутри вызова c.moveToFirst()
:
Caused by: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 776)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
В качестве обходного пути я мог бы попытаться использовать соединение с возможностью записи для записи, но я хотел бы знать, почему происходит сбой.
Таблица, которую я читаю, представляет собой стандартную таблицу SQLite:
CREATE TABLE BudgetVersions (
entityId VARCHAR PRIMARY KEY NOT NULL UNIQUE,
budgetId VARCHAR NOT NULL,
versionName VARCHAR NOT NULL,
dateFormat VARCHAR,
currencyFormat VARCHAR,
lastAccessedOn DATETIME,
isTombstone BOOL NOT NULL,
deviceKnowledge NUMERIC NOT NULL
);
Я видел, что авария произошла как на эмуляторе KitKat, так и на устройстве, работающем на Lollipop.
Существует отдельное записываемое соединение, открытое для одной и той же базы данных в то же время, принадлежащее WebView. База данных обновляется с помощью кода Javascript в WebView и читается на собственном уровне Android/Java с помощью этого подключения только для чтения.
Я ожидаю, что это может стать основной причиной проблемы, но я хотел бы подробно понять, почему соединение только для чтения будет мешать отдельному записываемому соединению.
Мне хорошо известно, что общий совет - использовать одно соединение с базой данных, но поскольку доступное для записи соединение принадлежит WebView
, у меня нет легкого доступа к нему из кода Java.