ConcurrentModificationException Room Android

Я использую 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);
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
525
1

Ответы 1

Это типичный сценарий, если вы пытаетесь вставить данные в список с разбивкой на страницы. Поскольку вы не вставили журналы ошибок, я предполагаю, что ошибка вызвана объектом 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/…

Ritu 22.06.2021 23:41

Другие вопросы по теме