房间android数据库被锁定

han*_* ke 5 database android android-room

我从生产\xe3\x80\x82\n错误分析期间发生异常。我的项目数据库有空间。项目中没有使用多进程。数据库机房已经封装了事务操作。我不知道为什么数据库被锁定。希望得到您的帮助\xef\xbc\x8c谢谢!

\n
this is exception\n\nProcess Name: 'com.geek.jk.weather'\nThread Name: 'kotlinx.coroutines.scheduling.CoroutineScheduler$Worker#DefaultDispatcher-worker-2'\nBack traces starts.\nandroid.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5)\n    at android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)\n    at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:553)\n    at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)\n    at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)\n    at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)\n    at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)\n    at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransaction(FrameworkSQLiteDatabase.java:1)\n    at androidx.room.RoomDatabase.beginTransaction(RoomDatabase.java:4)\n    at com.xiaoniu.unitionadbase.collie.dao.EventTrackDao_Impl$3.call(EventTrackDao_Impl.java:2)\n    at com.xiaoniu.unitionadbase.collie.dao.EventTrackDao_Impl$3.call(EventTrackDao_Impl.java:1)\n    at androidx.room.CoroutinesRoom$Companion$execute$2.invokeSuspend(CoroutinesRoom.kt:2)\n    at Rza.resumeWith(ContinuationImpl.kt:3)\n    at WIa.run(DispatchedTask.kt:18)\n    at androidx.room.TransactionExecutor$1.run(TransactionExecutor.java:1)\n    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)\n    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)\n    at java.lang.Thread.run(Thread.java:818)\n    Back traces ends.\n
Run Code Online (Sandbox Code Playgroud)\n

数据库

\n
@Database(entities = [CommonTrack::class, EventTrack::class], version = 1)\nabstract class TrackDatabase : RoomDatabase() {\nabstract fun CommonTrackDao(): CommonTrackDao\nabstract fun EventTrackDao(): EventTrackDao\n\ncompanion object {\n\n    private var instance: TrackDatabase? = null\n\n\n    fun getInstance(context: Context): TrackDatabase {\n        return instance ?: instance ?: buildDatabase(context).also { instance = it }\n        \n    }\n\n    fun buildDatabase(context: Context): TrackDatabase {\n        if (instance == null) {\n            instance = Room.databaseBuilder(\n                    context.applicationContext,\n                    TrackDatabase::class.java,\n                    "event_track.db"\n            ).allowMainThreadQueries().build()\n\n        }\n        return instance as TrackDatabase\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

}

\n

数据库使用情况

\n
@Dao\nabstract class EventTrackDao {\n\n@Query("select * from event_table limit 50 ")\nabstract suspend fun getEventTack():List<EventTrack>\n\n@Query("select count(*) from event_table")\nabstract suspend fun getEventCounts():Int\n\n@Insert(onConflict = OnConflictStrategy.REPLACE)\nabstract suspend fun insertEventTrack(events: List<EventTrack>):List<Long>\n\n@Insert(onConflict = OnConflictStrategy.REPLACE)\nabstract suspend fun insertEventTrack(event:EventTrack):Long\n\n\n@Delete\nabstract suspend  fun removeEvent(events: List<EventTrack>)\n
Run Code Online (Sandbox Code Playgroud)\n

}

\n
val call=  TrackDatabase.getInstance(context).EventTrackDao().insertEventTrack(eventslist)\n\nGlobalScope.launch(Dispatchers.IO) {\n                        runCatching {\n                            val \n                            list=TrackDatabase.getInstance(context).EventTrackDao().getEventCounts()\n\n                        }.onFailure {t ->\n                            \n                       }\n                    }\n
Run Code Online (Sandbox Code Playgroud)\n

EventTrackDao_Impl

\n
public final class EventTrackDao_Impl extends EventTrackDao {\nprivate final RoomDatabase __db;\n\nprivate final EntityInsertionAdapter<EventTrack> __insertionAdapterOfEventTrack;\n\nprivate final EntityDeletionOrUpdateAdapter<EventTrack> __deletionAdapterOfEventTrack;\n\npublic EventTrackDao_Impl(RoomDatabase __db) {\n  this.__db = __db;\n  this.__insertionAdapterOfEventTrack = new EntityInsertionAdapter<EventTrack>(__db) {\n  @Override\n  public String createQuery() {\n    return "INSERT OR REPLACE INTO `event_table` (`event_param`,`ts`) VALUES (?,?)";\n  }\n\n  @Override\n  public void bind(SupportSQLiteStatement stmt, EventTrack value) {\n    if (value.getParam() == null) {\n      stmt.bindNull(1);\n    } else {\n      stmt.bindString(1, value.getParam());\n    }\n    stmt.bindLong(2, value.getTs());\n  }\n};\nthis.__deletionAdapterOfEventTrack = new EntityDeletionOrUpdateAdapter<EventTrack>(__db) {\n  @Override\n  public String createQuery() {\n    return "DELETE FROM `event_table` WHERE `event_param` = ?";\n  }\n\n  @Override\n  public void bind(SupportSQLiteStatement stmt, EventTrack value) {\n    if (value.getParam() == null) {\n      stmt.bindNull(1);\n    } else {\n      stmt.bindString(1, value.getParam());\n    }\n  }\n};\n
Run Code Online (Sandbox Code Playgroud)\n

}\n}

\n

Tun*_*ken 2

由于锁定数据库,您的数据库类仍然允许多线程修改。Volatile使用和修改类数据库,synchronized如下所示:

@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
public abstract class WordRoomDatabase : RoomDatabase() {

   abstract fun wordDao(): WordDao

   companion object {
        // Singleton prevents multiple instances of database opening at the
        // same time. 
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(context: Context): WordRoomDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java, 
                        "word_database"
                    ).build()
                INSTANCE = instance
                // return instance
                instance
            }
        }
   }
}
Run Code Online (Sandbox Code Playgroud)

您必须使用 IO 上下文在协程作用域中调用插入操作。