Этот поток является продолжением проблемы Github по адресу: https://github.com/spring-projects/spring-data-r2dbc/issues/194
Контекст:
Привет,
Я только что попробовал очень простой пример, основанный на двухреактивные репозитории:
Дано br
, репо r2dbc crud и cr
, другое репо r2dbc crud:
br.findAll()
.flatMap(br -> {
return cr.findById(br.getPropertyOne())
.doOnNext(c -> br.setProperty2(c))
.thenReturn(br);
})
.collectList().block();
Этот пример кода никогда не завершается (сначала только 250, илипоэтому записи достигают оператора .collectList
).После некоторого копания добавление некоторого оператора onBackpressureXXX
после findAll
, кажется, "решает" проблему путем ... ну, удаления элементов или их буферизации.
На данный момент, насколько я понимаю, r2dbcРеактивные репозитории не используют механизм обратной связи с потребителем, который устраняет значительную часть преимуществ r2dbc.
Я ошибаюсь?Есть ли лучший способ достичь той же цели?
Спасибо!
Предложение от @ mp911de:
Избегайте создания потока, когда другой поток активен (Известная цитата: Не пересекайте потоки) как общее правило.
Если вы хотите получить связанные данные, в идеале соберите все результаты в виде List и подзапросов run.Таким образом, исходный поток ответов используется, и соединение может извлекать дополнительные результаты.
Что-то вроде следующего фрагмента должно выполнить работу:
br.findAll().collectList()
.flatMap(it -> {
List<Mono<Reference>> refs = new ArrayList<>();
for (Person p : it) {
refs.add(cr.findById(br.getPropertyOne()).doOnNext(…));
}
return Flux.concat(refs).thenReturn(it);
});
Но это удаляетПреимущество потоковой передачи данных без сохранения всего в памяти (мой последний шаг не в том, чтобы перечислять, а выполнять потоковую запись для вывода в какой-либо файл).
Есть ли какая-нибудь помощь по этому вопросу?