При работе с большими наборами данных Spring Data представляет две абстракции: Stream
и Page
.Мы использовали Stream
некоторое время, и у нас не было проблем, но недавно я захотел попробовать разбитый на страницы подход и столкнулся с проблемой надежности.
Примите во внимание следующее:
@Entity
public class MyData {
}
public interface MyDataRepository extends JpaRepository<MyData, UUID> {
}
@Component
public class MyDataService {
private MyDataRepository repository;
// Bridge between a Reactive service and a transactional / non-reactive database call
@Transactional
public void getAllMyData(final FluxSink<MyData> sink) {
final Pageable firstPage = PageRequest.of(0, 500);
Page<MyData> page = repository.findAll(firstPage);
while (page != null && page.hasContent()) {
page.getContent().forEach(sink::next);
if (page.hasNext()) {
page = repository.findAll(page.nextPageable());
}
else {
page = null;
}
}
sink.complete();
}
}
Используя две базы данных Postgres 9.5, исходная база данных имела около 100 000 строк, а место назначения было пустым.Затем этот пример кода использовался для копирования из источника в место назначения.В конце я обнаружил, что в моей целевой базе данных было гораздо меньшее количество строк, чем в исходном.
- Запуск в качестве приложения для весенней загрузки
- Поток, выполняющий копирование, использовал 4-6 потоковпараллельно (для скорости)
- Общее время выполнения не менее часа (макс. 2 часа)
Как оказалось, в конечном итоге я обрабатывал одни и те же строки несколько раз (и пропуская другие строки в результате).Это привело меня к обнаружению исправления, с которым уже сталкивались другие, где вы должны предоставить аргумент Sort.by("")
.
После изменения используемого сервиса:
// Make our pages sorted by the PKEY
final Pageable firstPage = PageRequest.of(0, 500, Sort.by("id"));
я обнаружил, что покаэто очень помогло, я все равно обработал бы несколько строк (от потери примерно половины строк до просмотра только ~ 12 дубликатов).Когда я использую Stream
вместо этого, у меня нет проблем.
У кого-нибудь есть какое-либо объяснение того, что происходит?Кажется, я не вижу дубликатов до тех пор, пока тест не будет запущен в течение как минимум 10-15 минут, что почти заставляет меня поверить, что происходит какой-то сеанс или другой тайм-аут (либо на клиенте, либо набаза данных), которая вызывает икоту.Но я действительно далеко за пределами своей области знаний для дальнейшего устранения неисправностей хех.