#java #hibernate #spring-data-jpa
Вопрос:
Я готовлю приложение spring, используя jpa с hibernate, чтобы сохранить несколько сотен миллионов строк в бд.
Я провожу некоторые тесты на меньшем источнике данных с 5 миллионами строк. Чтобы не хранить все данные в памяти до конца обработки, я сбрасываю данные каждые n-е строки. Код выглядит так:
AtomicLong counter = new AtomicLong();
destinationService.doInTransaction(() -> {
IntStream.range(0, (int) numberOfPages)
.boxed()
.peek(integer -> log.debug("Getting page: {}", integer 1))
.flatMap(i -> sourceRepository.findAll(PageRequest.of(i, pageSize)).get())
.flatMap(ETLService::map)
.peek(destinationService::save)
.map(measurement -> counter.getAndIncrement())
.peek(i -> {
if (i % jdbcBatchSize == 0) {
log.debug("Flushing. Objects counted: {}", i);
destinationService.flush();
}
})
.count();
return null;
});
Я включил показатели сеанса, и они показывают, что сброшено гораздо больше объектов:
2021-09-18 23:58:10.807 INFO 4680 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
3140100 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
21488800 nanoseconds spent preparing 584 JDBC statements;
0 nanoseconds spent executing 0 JDBC statements;
251780906500 nanoseconds spent executing 5828 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
2494336312500 nanoseconds spent executing 584 flushes (flushing a total of 1702357144 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}
Однако, если бы я удалил часть промывки из потока, она показывала бы один промыв с правильным количеством строк.
2021-09-18 23:04:55.562 INFO 11476 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
4869500 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
2912100 nanoseconds spent preparing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC statements;
250479981900 nanoseconds spent executing 5827 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
302878192900 nanoseconds spent executing 1 flushes (flushing a total of 5826561 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}
Почему при большем количестве сбросов в спящий режим перерасчет объектов?
Комментарии:
1. Я точно не знаю, но если вы считаете, что это ошибка, пожалуйста, создайте проблему в трекере проблем( hibernate.atlassian.net ) с тестовым случаем( github.com/hibernate/hibernate-test-case-templates/blob/master/… ), который воспроизводит проблему.