Комментарии 14
Но к этим объектам можно обратиться отдельными запросами зная userId или personId. Быстродействие от этого не пострадает.
Смелое заявление.
Поля имеют примитивные типы.
И это проблема, о которой тактично умалчивают в книгах и статьях про reactor. Типа вот есть r2dbc, в нем все можно, дерзайте. Но при этом на нем банальный join сделать — то еще приключение, особенно если хочется с удобством JPA, а не JdbcTemplate. А ведь в реальных проектах отношений может быть огромное количество.
На счет преимуществ нативного SQL над JPQL в плане быстродействия. Думаю, если провести голосование, то большинство отдаст голос в пользу SQL. Поэтому не такой уж я и смелый в своем мнении.
Что-то все в кучу смешалось. Первое — про утверждение, что пачка запросов вместо одного не скажется на производительности. А именно отдельно подтягивать данные вместо join (по userId или personId). Так вот, скажется. Это почти всегда будет медленнее, чем прогнать один запрос. И тут не должно быть сравнения с JPA, тут речь не про это, на чистом SQL будет медленнее.
Второе — про JPA. Конечно же, с JPA запросы зачастую будут менее оптимальные, чем написанные грамотным DBA. Но! Во многих категориях приложений это не критично. Гораздо важнее скорость разработки, удобство использования и поддержки. Особо критичные места всегда можно подтюнить или на крайний случай написать нативный запрос руками. И вот этого удобного механизма в реактивщине еще нет. И как мне кажется, этого очень не хватает, чтобы reactor начали использовать по настоящему массово.
Следует учесть, что WebFlux для работы требуется встроенный в Spring сервер Netty. Встроенные Tomcat и Jetty не подходят.
Олег Докука в книге "Практика реактивного программирования в Spring 5" пишет, что можно использовать и Tomcat, который теперь поддерживает асинхронность благодаря спецификации Servlet 3.1, просто это будет менее эффективно.
Ограничения во времени не требуется, так-как соединение происходит в отдельном потоке, не влияющем на основной.
Netty асинхронный, цикл событий может работать вообще в одном потоке и писать код лучше в расчёте на это. Обычно, используется пул с количеством потоков, равным количеству доступных ядер процессора, для полной утилизации ресурса.
На счет потоков. На разных уровнях под потоком понимается разное. Понятие поток в реактивном программировании (реактивный поток) это поток данных. Например Flux.merge(a, b, c) объединяет три потока. Для Netty поток, это скорее цепочка (или цикл) событий привязанных к определенным задачам. Здесь можно найти детали programmer.help/blogs/netty-basic-to-entry-2-netty-core-functions-and-thread-model.html A thread and task queue are maintained in NioEventLoop, which supports asynchronous submission and execution of tasks
[INFO ] 2021-07-03T15:17:18.268Z [main] org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean | | — Creating Service {urn:cam-ws}CamWSService from class ws.cam.CamWS
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-3] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-4] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-5] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-2] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-1] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
Это не я, это создатель Spring WebFlux.
Встроенные Tomcat и Jetty не подходят
Это неверно, на них можно переключиться, см документацию: https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-server-choice
Spring WebFlux: Реактивное программирование веб-сервисов