当前位置: 首页 > 面试题库 >

通过迁移升级Room DB会导致数据库锁定

西门品
2023-03-14
问题内容

我要回答我自己的问题,这是问题描述。

因此,我有一个应用程序已在商店中发布,并且由于要发布的新版本,数据库架构已更改,因此我自然不得不进行迁移,以将其从版本3升级到最新版本。
5.这包括提供从3迁移到4以及从4迁移到5的迁移,或者一次迁移从3迁移到5的迁移。

这就是我所做的,我提供了这些迁移,并将其提供给Room
databaseBuilder(),一切就绪,以模拟正在发生应用程序升级的情况(安装商店版本,运行它,登录,创建数据库,产生生产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)

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

  • 首先,我认为这是迁移的问题,但是迁移是正确的(检查了SQL,Room并没有抱怨任何类似的事情,通常它做得很好,并告诉您什么不匹配)。
  • 然后我以为问题是一次给它提供2个迁移(这是我之前做过的,没有问题),但是我删除了4到5个迁移并将其放在3到5个中以运行整个程序。一口气。没用
  • 然后我想好了,我总是可以放弃说好,只做 fallbackToDestructiveMigration() 并让Room重新创建所有内容,导致所有用户注销并丢失数据,这是我不想做的,但我只是想看看这将导致什么。因此,我没有提供这些迁移,只是忽略了它们。异常仍然发生。

该异常是无声发生的,它没有使应用程序崩溃,也没有引用我的代码中的任何地方,它仅发生在Logcat中,即使发生一次,也阻止了任何类型的数据库访问。无论您是否已提交迁移代码,或者是否希望退回至破坏性迁移,Room都会在检测到您已升级数据库时将其锁定,并阻止对它的任何访问。

我已经在三星S6,Nexus 5,OnePlus,摩托罗拉Moto C和Google Pixel上进行了测试,这些问题在所有地方都完全相同。


问题答案:

我在浏览有关将架构组件添加到您的应用程序的页面时,遇到了以下美好的一句话:

def room_version = "1.1.0" // or, for latest rc, use "1.1.1-rc1"

我自然使用的是Room版本 1.1.0 ,因为它应该是稳定的,我们当然需要稳定可靠的软件,我们可以从Google那里获得它。

将版本升级到 1.1.1-rc1
,我可以肯定地说这个由Google自己的代码引起的无意义的错误现在已经消失了,我已经在最初问题中提到的所有设备上重新测试了相同的场景。

当发生异常并且不提及您的代码时要当心。这是1.1.0室中的错误,请确认您是否已看过,我在网上看到的唯一对此提及是这是2017年以来的一个错误。



 类似资料:
  • 指导如何从Bootstrap v3.x升级到v4.x,重点是主要的变化,有什么新内容,以及哪些内容被移除了。 升级到 v4 Bootstrap 4 几乎是对整个项目进行了重写。其中最显著的变化都概括到了下面的内容,与以前相比,拥有了更多的具体的类以及把一些有关的部分变成了相关的组件。 当心!它在 flux 中工作的时候和在 v4 alphas 进程中工作是一致的。只有当它在不完整的情况下,我们才会

  • 迁移 Navicat Data Modeler 到新的电脑 在 Navicat Data Modeler,选择“Navicat Data Modeler”->“注册”。 【永久许可证】点击“取消激活”以在线取消激活许可证密钥。 【订阅方案】点击“退出”以退出你的 Navicat ID。 在现有的电脑解除安装 Navicat Data Modeler。 在新的电脑重新安装 Navicat Data

  • 迁移 Navicat Data Modeler 到新的电脑 在 Navicat Data Modeler,选择“帮助”->“注册”。 【永久许可证】点击“取消激活”以在线取消激活许可证密钥。 【订阅方案】点击“退出”以退出你的 Navicat ID。 在现有的电脑解除安装 Navicat Data Modeler。 在新的电脑重新安装 Navicat Data Modeler。 升级 Navica

  • 迁移 Navicat 到新的电脑 在 Navicat,选择“文件”->“导出连接”。导出的文件(.ncx)包含所有连接设置。 备份已导出的文件(.ncx)。 在 Navicat,选择“帮助”->“注册”。 【永久许可证】点击“取消激活”以在线取消激活许可证密钥。 【订阅方案】点击“退出”以退出你的 Navicat ID。 在现有的电脑解除安装 Navicat。 在新的电脑重新安装 Navicat。

  • 迁移 Navicat 到新的电脑 在 Navicat,选择“文件”->“导出连接”。导出的文件(.ncx)包含所有连接设置。 备份已导出的文件(.ncx)。 在 Navicat,选择“Navicat XXX”->“注册”。 【永久许可证】点击“取消激活”以在线取消激活许可证密钥。 【订阅方案】点击“退出”以退出你的 Navicat ID。 在现有的电脑解除安装 Navicat。 在新的电脑重新安装

  • 迁移 Navicat 到新的电脑 在 Navicat,选择“文件”->“导出连接”。导出的文件(.ncx)包含所有连接设置。 备份已导出的文件(.ncx)。 在 Navicat,选择“帮助”->“注册”。 【永久许可证】点击“取消激活”以在线取消激活许可证密钥。 【订阅方案】点击“退出”以退出你的 Navicat ID。 在现有的电脑解除安装 Navicat。 在新的电脑重新安装 Navicat。