Почему Spring не предоставляет реактивных (неблокирующих) клиентов для реляционных баз данных?

Я использовал набор инструментов Vert.x для создания реактивных приложений с поддержкой реляционных баз данных, таких как MySQL и Postgres. Я знаю, что Spring предоставляет реактивную поддержку для некоторых баз данных NoSQL, таких как Cassandra и Mongo, но готовы ли они предоставить то же самое для реляционных баз данных?


person Mohamed Elsayed    schedule 11.11.2018    source источник
comment
Spring WebFlux и rxjava2-jdbc от Роберта Б. Розера link.medium.com/6ONWHPEsKR   -  person uneq95    schedule 11.11.2018
comment
baeldung.com/rxjava-jdbc   -  person uneq95    schedule 11.11.2018
comment
github.com/davidmoten/rxjava2-jdbc   -  person uneq95    schedule 11.11.2018
comment
Работа над асинхронным JDBC все еще продолжается: blogs.oracle.com/java/   -  person duffymo    schedule 05.12.2018


Ответы (2)


В чем идея Spring Framework?

Spring Framework — это библиотека для повышения производительности разработчиков, как и портфельные проекты Spring, такие как Spring Data, Spring Security, Spring Cloud.

Эти проекты строятся на основе существующих API, которые либо стандартизированы посредством JSR или JEP, либо на основе библиотек, которые доказали свою полезность и широко используются. Команда Spring не создает драйверы для баз данных или других интеграций, это зависит от поставщиков баз данных/драйверов.

WebFlux по сравнению с Vert.x

Spring WebFlux — хороший пример типичного модуля Spring. Он строится поверх существующих неблокирующих серверов (Project Reactor через netty, Undertow и Jetty). WebFlux предоставляет контейнер времени выполнения для неблокирующих реактивных приложений, использующих компоненты Spring для помощи в разработке и запуске таких приложений.

Vert.x — отличный пример интегрированной среды, предоставляющей собственные низкоуровневые реализации. Vert.x сильно оптимизирован, и такая экосистема требует оптимизированных интеграций. Vert.x разработал собственные реализации для различных баз данных и предоставляет API, которые хорошо работают в контексте Vert.x, но эти API не являются JDBC.

API реляционных баз данных

Как уже упоминалось M-Razavi, Java использует JDBC для интеграции с реляционными базами данных, а JDBC носит блокирующий характер. ничего разумного нельзя было сделать, чтобы смягчить блокирующий характер JDBC. Разгрузка вызовов JDBC в пул Executor (обычно пул Thread) ограничена по своей полезности, поскольку пул в конечном итоге насыщается запросами). TL;DR, нет доступного API, поверх которого мы могли бы обеспечить реактивную интеграцию с реляционной базой данных.

Итак, какие есть варианты?

M-Razavi уже упоминал ADBA, который является инициативой Oracle по предоставлению стандартизированного API для асинхронного доступа к базе данных на Java с использованием фьючерсы. Все в ADBA все еще находится в стадии разработки, и команда ADBA рада получить отзывы. Группа разработчиков Postgres работает над драйвером Postgres ADBA, который можно использовать для первых экспериментов.

Тем не менее, ADBA — это будущая цель, и я ожидаю, что мы не увидим выпуск ADBA с Java 12.

Существует несколько независимых драйверов, таких как reactive-pg-client компании Reactiverse. Эти драйверы поставляются с API-интерфейсом конкретного поставщика и не очень подходят для более широкой интеграции в Spring. Нам потребуется предоставить дополнительные уровни для предоставления общего API, а новые драйверы нельзя будет просто подключить к вашему приложению, чтобы оно работало «из коробки». Наличие стандартного API обеспечивает возможность подключения, поэтому наличие стандартного API имеет огромную ценность.

R2DBC спешит на помощь?

Из-за отсутствия стандартного API и отсутствия драйверов команда Pivotal начала исследовать реактивный реляционный API, который мог бы идеально подходит для целей реактивного программирования. Они придумали R2DBC, что означает реактивное подключение к реляционной базе данных. На данный момент R2DBC является проектом-инкубатором для оценки осуществимости и начала дискуссий о том, заинтересованы ли поставщики драйверов в поддержке реактивных/неблокирующих/асинхронных драйверов.

На данный момент существует три реализации драйвера:

R2DBC поставляется со спецификацией API (r2dbc-spi) и клиентом (r2dbc-client), который позволяет использовать SPI для приложений. Мы начали изучать интеграцию Spring Data R2DBC, которая предоставляет реактивные API через клиент базы данных. и поддерживая реактивные репозитории.

R2DBC и его экосистема все еще молоды и нуждаются в экспериментах и ​​отзывах, чтобы собрать примеры использования и посмотреть, имеет ли смысл реактивная интеграция реляционной базы данных.

Прямо сейчас вы можете использовать R2DBC через Spring Data, и следующий фрагмент показывает использование DatabaseClient:

PostgresqlConnectionFactory connectionFactory = new PostgresqlConnectionFactory(…);

DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);

Mono<Integer> count = databaseClient.execute()
                .sql("INSERT INTO legoset (id, name, manual) VALUES($1, $2, $3)")
                .bind("$1", 42055)
                .bind("$2", "Description")
                .bindNull("$3", Integer.class)
                .fetch()
                .rowsUpdated();

Flux<Map<String, Object>> rows = databaseClient.execute()
                .sql("SELECT id, name, manual FROM legoset")
                .fetch()
                .all();
person mp911de    schedule 05.12.2018
comment
Можете ли вы обновить свой ответ, добавив поддержку R2DBC MySQL? Ваше здоровье - person nicolasl; 29.08.2019
comment
Тем временем проект ADBA был прекращен. - person Imaskar; 03.11.2019

Spring WebFlux — отличный способ создать неблокирующее приложение REST. Одна из проблем, с которой вы сталкиваетесь, когда начинаете работать с WebFlux, — это JDBC, потому что JDBC блокирует. Новые школьные базы данных, такие как Cassandra или Couchbase, имеют неблокирующие драйверы. В случае с Couchbase его драйвер использует RXJava. Предпринимаются определенные усилия по созданию асинхронных драйверов для баз данных, а также усилия Oracle по созданию ADBA. К сожалению, это только начало, и если вы хотите общаться с базой данных SQL на JVM, вам придется столкнуться с блокирующим драйвером.
На самом деле Spring не несет ответственности за предоставление неблокирующего драйвера для реляционных баз данных.

person M-Razavi    schedule 11.11.2018
comment
Я не знаю, почему за это проголосовали, но я также читал, что jdbc блокирует по своей природе. - person uneq95; 11.11.2018
comment
Вы правы, но мне интересно, поскольку я упоминал, что другие инструменты, такие как Vert.x, предоставляют асинхронные клиенты для реляционных баз данных. - person Mohamed Elsayed; 11.11.2018
comment
Большую часть времени эти инструменты накладывают помаду на блокирующий клиент БД (выполняя его в управляемом пуле потоков, который имеет тот же размер, что и пул соединений) и называют его реактивным. см. напр. stackoverflow.com/ вопросы/50432154/ - person Simon Baslé; 07.12.2018
comment
хм... кажется, правда, я не знал этого раньше. - person Mohamed Elsayed; 08.12.2018
comment
Я читал, что нет смысла использовать Reactor с блокирующей базой данных (например, JDBC), поскольку база данных будет удерживать поток в ожидании, пока он извлекает данные. о чем ты думаешь? - person Christopher Barrett; 28.05.2019