han*_* ke 5 database android android-room
我从生产\xe3\x80\x82\n错误分析期间发生异常。我的项目数据库有空间。项目中没有使用多进程。数据库机房已经封装了事务操作。我不知道为什么数据库被锁定。希望得到您的帮助\xef\xbc\x8c谢谢!
\nthis 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.\nRun 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}\nRun 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>)\nRun Code Online (Sandbox Code Playgroud)\n}
\nval 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 }\nRun Code Online (Sandbox Code Playgroud)\nEventTrackDao_Impl
\npublic 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};\nRun Code Online (Sandbox Code Playgroud)\n}\n}
\n由于锁定数据库,您的数据库类仍然允许多线程修改。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 上下文在协程作用域中调用插入操作。