通过迁移升级Room DB会导致数据库锁定 [英] Upgrading Room DB with migrations causes DB lock

查看:270
本文介绍了通过迁移升级Room DB会导致数据库锁定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

因此,我有一个应用程序已在商店中发布,并且由于要发布的新版本,数据库架构已更改,因此我自然不得不进行迁移,以将其从版本3升级到版本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自己的代码引起的无意义的错误现在已经消失了,我已经在所有设备上重新测试了相同的场景我在最初的问题中提到过.

在发生异常并且不提及您的代码时要当心.这是Room 1.1.0中的错误,请确认您是否已查看过,这是我在网上看到的唯一对此提及 解决方案

I was browsing this page on adding Architecture Components to your app and I came across this beautiful line:

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

I was using Room version 1.1.0, naturally, because it should be stable and we want stable, solid software that we can rely on from Google, of course.

Bumped up the version to 1.1.1-rc1 and I can safely say that this nonsensical error that stems from Google's own code is now gone, I've retested the same scenario on all the devices I mentioned in the original question.

Be careful when exceptions occur and no mention of your code is included. This is a bug in Room 1.1.0, please confirm if you have seen it, the only other mention of it online that I've seen is this one here from 2017

这篇关于通过迁移升级Room DB会导致数据库锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆