我有一個只讀的數據庫連接。有時,當用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
);
我見過的碰撞發生在既有奇巧模擬器運行棒棒糖的裝置。
有一個單獨寫開到同一個數據庫同時連接,由web視圖擁有。數據庫正在通過WebView中的Javascript代碼進行更新,並使用此只讀連接從本機Android/Java層讀取。
我希望這可能被證明是問題的根本原因,但我想詳細瞭解爲什麼只讀連接會干擾單獨的可寫連接。
我知道一般的建議是使用單一連接到數據庫,但由於可寫連接歸WebView
所有,所以我不能從Java代碼中輕鬆訪問它。
請注意,'cwac-loaderex'已停用相當長一段時間。這是您在開發過程中看到的崩潰,還是僅在生產過程中看到的?請注意,'getCount()'實際上是在執行你要加載器加載的SQL查詢,因爲'rawQuery()'/'query()'返回一個'Cursor',但不會立即執行查詢。 – CommonsWare
刪除了裝載機和CWAC-LoaderEx的提及。如果沒有他們,問題也會發生。在開發過程中發生崩潰。 –
我會說這是sqlite如何根據標誌返回數據庫實例的一個bug,可能與多線程相關。我會假設試圖爲你的所有操作保存一個可讀寫數據庫的單例實例應該解決它(也打開你所有的讀寫連接) – njzk2