Spring data Page / Pageable возвращает дубликаты на больших наборах данных? - PullRequest
1 голос
/ 10 мая 2019

При работе с большими наборами данных 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 минут, что почти заставляет меня поверить, что происходит какой-то сеанс или другой тайм-аут (либо на клиенте, либо набаза данных), которая вызывает икоту.Но я действительно далеко за пределами своей области знаний для дальнейшего устранения неисправностей хех.

...