Я использую Room в своем приложении, и при вставке данных в мой db время от времени выдается ConcurrentModificationException. Почему это так?
Я использую api для разбивки на страницы, и после каждого вызова api я вставляю dataList в свой db, используя
new Thread(new Runnable() {
@Override
public void run() {
appDatabase.dataDao().insertMultipleData(dataList);
}
}).start();
где
appDatabase = Room.databaseBuilder(context, AppDatabase.class, AppDatabase.DATABASE_NAME)
.fallbackToDestructiveMigration()
.build();
Вставить операцию
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertMultipleData(List<Data> dataList);




Это типичный сценарий, если вы пытаетесь вставить данные в список с разбивкой на страницы. Поскольку вы не вставили журналы ошибок, я предполагаю, что ошибка вызвана объектом dataList. В этом случае сообщение об ошибке будет выглядеть, как показано ниже.
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at androidx.room.EntityInsertionAdapter.insertAndReturnIdsArray(EntityInsertionAdapter.java:131)
at com.myApp.data.database.entities.FeedDataDao_Impl.insertAll(FeedDataDao_Impl.java:220)
В этом случае ошибка вызвана параллельным изменением одной и той же переменной разными потоками. В этом случае я предполагаю, что вы вставляете данные в базу данных и одновременно выполняете новый вызов службы (разбиение на страницы) для извлечения данных, обновляющих один и тот же объект данных. Или это может быть брошено, даже если вы удалите содержимое из исходного источника массива во время его вставки. Решение довольно простое. Вы можете скопировать переменную dataList в новую переменную и использовать новую локальную переменную в качестве параметра для вашего вызова вставки.
Например: (Котлин)
val localCopy = dataList
CoroutineScope(Dispatchers.IO).launch {
AppDatabase.getDatabase(context).feedDataDao().insertAll(localCopy).size
}.invokeOnCompletion {
Log.d("Inserted all items")
}
Например: (Java)
List<MyDataType> localCopy = dataList
AppDatabase.getDatabase(context).feedDataDao().insertAll(localCopy).size
У меня такая же проблема, но это решение не работает для меня. Пожалуйста, проверьте stackoverflow.com/questions/68082863/…