SQLite事务和Kotlin协程结合使用需要特别特别注意
suspend fun test(bsc:BookSourceConfig){
val db = DBManager.openDatabaseW()
if (db != null) {
db.beginTransaction()
try {
testA(db,bsc)
testB(db, bsc)
db.setTransactionSuccessful()
} finally {
db.endTransaction()
}
}
}
当testA和testB不在同一线程执行时setTransactionSuccessful和endTransaction都不能被执行。测试为了每次TestA和TestB都是在不同线程执行,在testA 重使用async,如下
private suspend fun testA(db: SQLiteDatabase,bsc:BookSourceConfig) = withContext(Dispatchers.IO){
async {
val whereClause = "${BookSourceConfigSchema.KEY_KEY} = ?"
val whereArgs = arrayOf(bsc.id.toString())
val num = db.delete(BookSourceConfigSchema.TABLE_NAME, whereClause, whereArgs) > 0
}
}
private suspend fun testB(db: SQLiteDatabase,bsc:BookSourceConfig) = withContext(Dispatchers.IO){
val values = getContentValues(bsc)
var num = db.insert(BookSourceConfigSchema.TABLE_NAME, null, values).toInt()
}
这样每次都会出 如下错误:
W/SQLiteConnectionPool: The connection pool for database '/data/data/xxx.xx.xx/databases/xxxx' has been unable to grant a connection to thread 2107 (DefaultDispatcher-worker-4) with flags 0x2 for 540.01105 seconds. Connections: 0 active, 1 idle, 0 available.
原因如下图
图片来自# Kotlin 协程和 Android SQLite API 中的线程模型
网友评论