Я работаю над проектом, к которому я, к сожалению, не могу использовать ROOM для доступа к базе данных, потому что он сильно зависит от курсоров, которые читают базы данных, созданные в результате вызовов API
Так что для этой работы я использую обычный SQLiteOpenHelper
для получения readableDatabase
и выполнения запросов с использованием чего-то вроде
withContext(Dispatchers.IO) { db.execSQL(.....) }
Я столкнулся с проблемой с транзакциями, которые создали взаимоблокировки, например, это может вызвать проблемы
suspend fun readDataFromServer() {
withContext(dispatchers.IO) { db.beginTransaction() }
val inputStream = withContext(dispatchers.IO) { client.getDataStream() }
while(true) {
withContext(dispatchers.IO) { //code here that reads from the input stream until it finds a separator
}
withContext(dispatchers.Default) {
//code that does some calculations that may take anywhere from 500 to 1500 ms
}
withContext(dispatchers.IO) {
//code that saves the data in the appropriate form in my db
}
}
withContext(dispatchers.IO) {
db.setTransactionSuccessful()
db.endTransaction()
}
}
(обратите внимание, что вышеприведенный код не совсем подходит для моего фиктивного кода, у меня нет доступа к моему проекту atm)
Я исследовал его, и, похоже, проблема заключалась в том, что транзакция должна start и fini sh в одном и том же потоке, поэтому, когда я использовал withContext для изменения диспетчеров (даже если это был тот же диспетчер), это привело бы к тупику
В конце я решил свою проблему, обернув вся функция в одном с контентом, но я заметил кое-что любопытное
обычно функция начиналась бы примерно так:
* 10 18 *
и это вызвало бы зависание, но когда я попытался запустить его от других диспетчеров, это сработало бы, поэтому
launch(Dispatchers.Default) {
readDataFromServer()
}
и
launch(Dispatchers.IO) {
readDataFromServer()
}
оба, кажется, работают
Мне было интересно, почему это так, и может ли это быть случайностью, потому что, по сути, я не использую более одного потока для своих операций
заключает его в один и тот же с помощью Context правильный ответ ? или может использовать запуск (Dispatchers.Default) тоже правильно?
Я спрашиваю, потому что между чтением с сервера и записью в базу данных я выполняю довольно интенсивную работу, и мне кажется, что неправильно делать это которые работают в диспетчере ввода-вывода вместо стандартного