Что нужно помнить при многопоточности Realm DB

Realm - одна из лучших альтернатив SQLite DB в Android. Его действительно легко настроить, и с ним весело работать. Поскольку realm lazy загружает данные, их читать очень быстро.

У Realm есть свои болевые точки, самая большая из которых - многопоточность. Управляемые объекты области (объекты, которые читают из области) не могут передаваться между потоками, если вы не преобразовали их в POJO. Запись в область в некоторых случаях очень медленная (когда у вас есть слушатели для элемента, который вы изменяете).

Вот некоторые вещи, которые следует помнить при использовании области в нескольких потоках

Максимальный размер асинхронной очереди - 100

Довольно легко написать что-нибудь в области в асинхронном режиме, используя метод executeTransactionAsync, подобный этому

Вот в чем загвоздка. Существует ограничение на количество элементов, которые могут быть добавлены в эту очередь транзакций. Если количество транзакций, добавленных в очередь, больше 100, Realm DB выдаст ошибку. Поэтому, если вы записываете много элементов за один раз, убедитесь, что вы пишете в одной транзакции, а не добавляете ее как разные транзакции.

Вышеуказанный метод не рекомендуется. Лучше писать одной транзакцией.

Нужен обработчик темы

Для управления параллелизмом Realm использует MVCC (Multi-version Concurrency Control). Каждый поток получает моментальный снимок БД в тот конкретный момент времени, когда создается экземпляр области. При изменении данных моментальный снимок обновляется, и вы получаете самые свежие данные. Но снимок обновляется только в том случае, если у потока есть петлитель. Если у вас есть экземпляр области в потоке A, у которого нет цикла, и новая запись записывается в БД из потока B. Экземпляр области в потоке A не сможет увидеть новые данные.

Поэтому, если у вас есть экземпляр области, который будет открыт в течение длительного времени, лучше быть в потоке обработчика.

Если вам случайно понадобится экземпляр области в потоке без цикла, и вы хотите обновить моментальный снимок БД, вы можете использовать realm.refresh() для обновления моментального снимка области.

Наличие нескольких экземпляров

Когда вы используете несколько экземпляров области, работающей в нескольких потоках, вы должны понимать связанные с этим затраты. Когда вы создаете новый экземпляр области, он занимает много памяти. Поэтому, если вы не закрываете область после того, как закончите с ней, или у вас есть большое количество потоков, использующих область одновременно. Есть вероятность, что вы можете получить исключение нехватки памяти. Следовательно, лучше иметь ограниченное количество экземпляров открытой области в любой момент времени.

Realm.getGlobalInstanceCount(Realm.getDefaultConfiguration()) можно использовать для определения количества активных экземпляров области.

Всегда используйте try with resources в Java или use в kotlin, чтобы закрыть экземпляр области после использования.

Вышеупомянутое - это некоторые вещи, которые следует помнить при использовании Realm в многопоточной среде.
~ Удачного кодирования ~