簡體   English   中英

為什么此連接是只讀的?

[英]Why is this connection read-only?

我將greenDao用作ORM,現在由於性能問題,我試圖使應用程序成為多線程。 這是我打開連接的方式:

class appClass extends Application{
@Override    
public void onCreate(){
     DaoMaster.OpenHelper helper = new DaoMaster.OpenHelper(this, "my-db", null);
     final SQLiteDatabase db = helper.getWritableDatabase();
     final DaoMaster daoMaster = new DaoMaster(db);
     daoSession = daoMaster.newSession();
}

有時應用程序與此崩潰

.SQLiteException:無法執行此語句,因為它可能會修改數據庫,但連接是只讀的。

這是Stacktrace:

java.lang.RuntimeException:無法恢復活動{com.my.app.android/com.my.app.android.ui.ListActivity}:android.database.sqlite.SQLiteException:無法執行此語句,因為它可能會修改數據庫但是連接是只讀的。 在android.app.ActivityThread.performResumeActivity(ActivityThread.java:3581)在android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3621)在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1638)在android。 os.Handler.dispatchMessage(Handler.java:106)在android.os.Looper.loop(Looper.java:164)在android.app.ActivityThread.main(ActivityThread.java:6494)在java.lang.reflect.Method com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:438)上的.invoke(本機方法),com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)上的.invoke .database.sqlite.SQLiteException:無法執行此語句,因為它可能會修改數據庫,但連接是只讀的。 在android.database.sqlite.SQLiteConnection.throwIfStatementForbidden(SQLiteConnection.java:1026)在android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:730)在android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754) )在android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)在android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1754)在android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java: 1682)在com.my.app.android.orm.generated.ObjektDao.deleteOPTempTable(ObjektDao.java:479)在com.my.app.android.orm.generated.ObjektDao.reBuildOPTempTable(ObjektDao.java:544) .com.my.app.android.ui.ListActivity.onRestart(ListActivity.java:94)上的.my.app.android.TempTablesUtils.checkTempTables(TempTablesUtils.java:132)在android.app.Instrumentation.callActivityOnRestart(Instrumentation.java :1344)at android.app.Activity.performRestart(Activity.java:7088)at android.ap p.Activity.performResume(Activity.java:7099)位於android.app.ActivityThread.performResumeActivity(ActivityThread.java:3556)...還有8個

在這種情況下,為什么連接是只讀的?

可能是您已經有可能尚未關閉的連接。

更具體地說,該消息是從SQLiteConnection.java中發出的。第709-714行是:-

private void throwIfStatementForbidden(PreparedStatement statement) {
    if (mOnlyAllowReadOnlyOperations && !statement.mReadOnly) {
        throw new SQLiteException("Cannot execute this statement because it "
                + "might modify the database but the connection is read-only.");
    }
}

文件中的注釋包括:-

/ ** *表示一個SQLite數據庫連接。 *每個連接都包裝一個本地sqlite3對象的實例。 *

*啟用數據庫連接池后,到同一個數據庫可以有多個活動的*連接。 否則,每個數據庫通常只有一個*連接。 *

*啟用SQLite WAL功能時,多個讀取器和一個寫入器*可以同時訪問數據庫。 沒有WAL,讀者和作家*是互斥的。 *

* *

所有權和並發保證

*

*連接對象不是線程安全的。 根據需要獲取它們以執行數據庫操作,然后將其返回到池中。 在任何給定的時間,一個連接都由{@link SQLiteSession}對象或{@link SQLiteConnectionPool}擁有和使用。 這些類負責序列化操作,以防止並發使用連接。 *

*擁有一個所有者的保證使該類得以實現*不帶鎖,從而大大簡化了資源管理。 *

* *

封裝保證

*

*連接對象對象擁有與連接關聯的所有與SQLite相關的本機對象。 此外,系統中沒有其他對象能夠獲取這些本機對象的句柄。 因此,當連接關閉時,我們不必擔心其他組件可能引用其關聯的SQLite狀態-沒有關系。 *

封裝是確保連接對象的生命周期不會變成終結器和引用隊列的煎蛋。 *

* * @隱藏* /

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM