相关疑难解决方法(0)

使用迁移升级Room DB会导致数据库锁定

我将回答我自己的问题,这是问题描述.

所以我有一个在商店发布的应用程序,并且我想要发布的新版本,数据库模式已经改变,所以我自然不得不进行迁移,负责将其从版本3升级到最新版本这包括提供3到4和4到5的迁移.或者一次性从3到5.

这就是我所做的,我提供了这些迁移并将它们提供给Room databaseBuilder(),并且所有内容都已到位以模拟应用程序升级的场景(安装Store版本,运行它,登录,创建DB,生产生产APK并通过终端安装在设备上,运行)

这样做总是产生以下异常:

05-19 02:38:00.363 6472-6522/co.myapp.app E/ROOM: Invalidation tracker is initialized twice :/.
05-19 02:38:00.378 6472-6549/co.myapp.app E/ROOM: Cannot run invalidation tracker. Is the db closed?
java.lang.IllegalStateException: The database '/data/user/0/co.myapp.app/databases/my_db' is not open.
at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2765)
at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:490)
at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:88)
at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:87)
at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:160)
at java.lang.ThreadLocal.get(ThreadLocal.java:150)
at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:484)
at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:107)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45)
at android.arch.persistence.room.InvalidationTracker$1.run(InvalidationTracker.java:321)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)
Run Code Online (Sandbox Code Playgroud)

迁移成功运行并且正在按照我的编写创建表,但是在Room升级数据库版本并迁移之后,该异常一直出现在每个数据库访问操作上.升级后的每次读取或写入都会导致此异常

  • 首先我认为这是迁移的一个问题,但迁移是正确的(SQL已被检查,Room没有抱怨任何类型的东西,通常情况非常好,并告诉你什么不匹配).
  • 然后我认为问题在于同时为它提供2次迁移(我以前做过,并且没有问题)但我删除了4到5次迁移并将其放在3到5之间以运行整个事情一个人去.没用
  • 然后我想好了,我总是可以放弃并说好,只需做fallbackToDestructiveMigration()并让Room重新创建所有内容,导致所有用户退出并丢失数据,这是我不想做但我只是想要的看看这会导致什么.所以我没有提供迁移,只是忽略了它们.例外仍然发生.

这个异常是静默发生的,它没有崩溃应用程序,也没有引用我的代码中的任何地方,它只是发生在Logcat中,并且在它发生甚至一次时阻止了任何类型的数据库访问.无论您是否已经提供了迁移代码,或者您是否想要回退到破坏性迁移,当Room检测到您已升级数据库时,它会将其锁定并阻止对其进行任何访问.

我已经在三星S6,Nexus 5,OnePlus,摩托罗拉Moto C和Google Pixel上测试了这一点,到处都是完全相同的问题.

sql android android-room

9
推荐指数
1
解决办法
1899
查看次数

重新打开 ROOM 数据库

我正在尝试关闭然后重新打开 Room 数据库。(目的是备份SQLite文件)

这是我关闭它的方式:

public static void destroyInstance() {
    if (INSTANCE != null && INSTANCE.isOpen()) {
        INSTANCE.close();
    }
    INSTANCE = null;
}
Run Code Online (Sandbox Code Playgroud)

INSTANCE 是一个RoomDatabase对象

并重新打开我通过调用再次初始化 INSTANCE 对象:

Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, C.ROOM_DB_NAME)
Run Code Online (Sandbox Code Playgroud)

在我转到另一个活动后,我在 logcat 中看到此错误: E/ROOM: Invalidation tracker is initialized twice

SELECT 查询工作正常,但 INSERT 失败并出现以下错误:

E/SQLiteLog: (1) no such table: room_table_modification_log

E/ROOM: Cannot run invalidation tracker. Is the db closed?
java.lang.IllegalStateException: The database '/data/user/0/ro.example.example/databases/mi_room.db' is not open.
Run Code Online (Sandbox Code Playgroud)

虽然 INSTANCE.isOpen() 返回 true

房间版本:1.1.1

有谁知道这个“room_table_modification_log”表是什么?

android android-sqlite android-room

7
推荐指数
1
解决办法
2622
查看次数

标签 统计

android ×2

android-room ×2

android-sqlite ×1

sql ×1