You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库随机出现SQLiteDatabaseLockedException崩溃求助

问题

在Firebase Crashlytics中收到随机触发的崩溃日志,开发阶段从未捕获到该异常:

Fatal Exception:
android.database.sqlite.SQLiteDatabaseLockedException: database is locked (Sqlite code 5), (OS error - 11:Try again)
        at android.database.sqlite.SQLiteConnection.nativeExecute(SQLiteConnection.java)
        at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:591)
        at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:332)
        at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:311)
        at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:532)
        at android.database.sqlite.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:467)
        at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransactionNonExclusive(FrameworkSQLiteDatabase.java:78)
        at androidx.room.RoomDatabase.internalBeginTransaction(RoomDatabase.java:570)
        at androidx.room.RoomDatabase.beginTransaction(RoomDatabase.java:555)
        at androidx.work.impl.utils.StopWorkRunnable.run(StopWorkRunnable.java:56)
        at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
        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:776)

使用Room作为数据库,已尝试更新Room版本但问题未解决,请问是否可自行修复该问题?是否需要添加数据库相关配置参数?

解决方案

这个崩溃是WorkManager执行StopWorkRunnable时尝试开启Room事务,遭遇SQLite数据库锁定导致的,可通过以下方式修复:

  • 保证Room操作的线程安全:
    Room要求数据库操作不在主线程执行,但多线程(包括WorkManager后台线程)同时发起写操作仍会触发锁定。确保所有Room操作通过@Dao的suspend方法配合协程执行,避免手动开启事务后未及时提交/回滚,防止数据库连接长期被占用。

  • 配置SQLite超时重试与线程池:
    在构建RoomDatabase时,设置SQLite的busy_timeout参数让数据库遇到锁定时自动重试,同时可指定单线程查询池避免并发冲突:

    Room.databaseBuilder(context, YourDatabase::class.java, "your_db_name")
        .setQueryExecutor(Executors.newSingleThreadExecutor())
        .addCallback(object : RoomDatabase.Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                super.onCreate(db)
                // 设置5秒超时,期间自动重试锁定操作
                db.execSQL("PRAGMA busy_timeout = 5000;")
            }
        })
        .build()
    
  • 优化WorkManager任务的数据库操作:
    检查Worker实现中是否存在未完成的事务或长时间占用数据库的操作。确保Worker内的数据库操作尽量简短,执行完成后及时释放连接;若需处理大量数据,拆分任务避免长时间持有锁。

  • 确认WAL模式启用:
    Room默认启用WAL(Write-Ahead Logging)模式,该模式能提升并发性能、减少写操作锁定时间。可显式配置确保启用:

    Room.databaseBuilder(context, YourDatabase::class.java, "your_db_name")
        .setJournalMode(RoomDatabase.JournalMode.WAL)
        .build()
    
  • 避免跨进程访问数据库:
    若App存在多进程,确保仅单个进程访问Room数据库,或通过ContentProvider封装数据库操作,防止多进程同时写导致锁定。

内容的提问来源于stack exchange,提问作者Verona1024

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:10:13