[英]room android database is locked
I had been getting " android.database.sqlite.SQLiteDatabaseLockedException" exception from production。 An exception occurred during error analysis.my project database is room.我从生产中收到“android.database.sqlite.SQLiteDatabaseLockedException”异常。错误分析期间发生异常。我的项目数据库是房间。 Multi-process is not used in the project.The database room has encapsulated transaction operations.
项目中没有使用多进程。库房已经封装了事务操作。 I don't know why the database is locked.
我不知道为什么数据库被锁定。 Hope to get your help,thanks!
希望能得到您的帮助,谢谢!
this is exception
Process Name: 'com.geek.jk.weather'
Thread Name: 'kotlinx.coroutines.scheduling.CoroutineScheduler$Worker#DefaultDispatcher-worker-2'
Back traces starts.
android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5)
at android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:553)
at android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)
at android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)
at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransaction(FrameworkSQLiteDatabase.java:1)
at androidx.room.RoomDatabase.beginTransaction(RoomDatabase.java:4)
at com.xiaoniu.unitionadbase.collie.dao.EventTrackDao_Impl$3.call(EventTrackDao_Impl.java:2)
at com.xiaoniu.unitionadbase.collie.dao.EventTrackDao_Impl$3.call(EventTrackDao_Impl.java:1)
at androidx.room.CoroutinesRoom$Companion$execute$2.invokeSuspend(CoroutinesRoom.kt:2)
at Rza.resumeWith(ContinuationImpl.kt:3)
at WIa.run(DispatchedTask.kt:18)
at androidx.room.TransactionExecutor$1.run(TransactionExecutor.java:1)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Back traces ends.
database数据库
@Database(entities = [CommonTrack::class, EventTrack::class], version = 1)
abstract class TrackDatabase : RoomDatabase() {
abstract fun CommonTrackDao(): CommonTrackDao
abstract fun EventTrackDao(): EventTrackDao
companion object {
private var instance: TrackDatabase? = null
fun getInstance(context: Context): TrackDatabase {
return instance ?: instance ?: buildDatabase(context).also { instance = it }
}
fun buildDatabase(context: Context): TrackDatabase {
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
TrackDatabase::class.java,
"event_track.db"
).allowMainThreadQueries().build()
}
return instance as TrackDatabase
}
}
} }
Database usage数据库使用
@Dao
abstract class EventTrackDao {
@Query("select * from event_table limit 50 ")
abstract suspend fun getEventTack():List<EventTrack>
@Query("select count(*) from event_table")
abstract suspend fun getEventCounts():Int
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract suspend fun insertEventTrack(events: List<EventTrack>):List<Long>
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract suspend fun insertEventTrack(event:EventTrack):Long
@Delete
abstract suspend fun removeEvent(events: List<EventTrack>)
} }
val call= TrackDatabase.getInstance(context).EventTrackDao().insertEventTrack(eventslist)
GlobalScope.launch(Dispatchers.IO) {
runCatching {
val
list=TrackDatabase.getInstance(context).EventTrackDao().getEventCounts()
}.onFailure {t ->
}
}
EventTrackDao_Impl EventTrackDao_Impl
public final class EventTrackDao_Impl extends EventTrackDao {
private final RoomDatabase __db;
private final EntityInsertionAdapter<EventTrack> __insertionAdapterOfEventTrack;
private final EntityDeletionOrUpdateAdapter<EventTrack> __deletionAdapterOfEventTrack;
public EventTrackDao_Impl(RoomDatabase __db) {
this.__db = __db;
this.__insertionAdapterOfEventTrack = new EntityInsertionAdapter<EventTrack>(__db) {
@Override
public String createQuery() {
return "INSERT OR REPLACE INTO `event_table` (`event_param`,`ts`) VALUES (?,?)";
}
@Override
public void bind(SupportSQLiteStatement stmt, EventTrack value) {
if (value.getParam() == null) {
stmt.bindNull(1);
} else {
stmt.bindString(1, value.getParam());
}
stmt.bindLong(2, value.getTs());
}
};
this.__deletionAdapterOfEventTrack = new EntityDeletionOrUpdateAdapter<EventTrack>(__db) {
@Override
public String createQuery() {
return "DELETE FROM `event_table` WHERE `event_param` = ?";
}
@Override
public void bind(SupportSQLiteStatement stmt, EventTrack value) {
if (value.getParam() == null) {
stmt.bindNull(1);
} else {
stmt.bindString(1, value.getParam());
}
}
};
} } } }
Your database class still allow multithread modify due to lock database.由于锁定数据库,您的数据库 class 仍然允许多线程修改。 Modify class database with
Volatile
and synchronized
like this:使用
Volatile
修改 class 数据库并像这样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
}
}
}
}
You must call insert action in coroutine scope with IO context.您必须在带有 IO 上下文的协程 scope 中调用插入操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.