Why does Spring not provide reactive (non-blocking) clients for relational databases?

╄→尐↘猪︶ㄣ 提交于 2019-12-03 09:28:09

问题


I've used Vert.x toolkit for creating reactive applications with support for relational DBs like MySQL and Postgres. I know Spring provides reactive support for some NoSQL DBs like Cassandra and Mongo but are they willing to provide the same for relational DBs?


回答1:


What's the idea behind the Spring Framework?

Spring Framework is a library to improve developer productivity, and so are Spring's portfolio projects such as Spring Data, Spring Security, Spring Cloud.

These projects build on top of existing APIs which are either standardized through a JSR or a JEP or on top of libraries that have proved to be useful and widely used. The Spring team does not build drivers for databases or other integrations, that's up to the database/driver vendors.

WebFlux compared to Vert.x

Spring WebFlux is an good example for a typical Spring module. It builds on top of existing non-blocking servers (Project Reactor via netty, Undertow, and Jetty). WebFlux provides a runtime container for non-blocking, reactive applications leveraging Spring components to assist in developing and running such applications.

Vert.x is an excellent example of an integrated environment that provides its own low-level implementations. Vert.x is heavily optimized and such an eco-system requires optimized integrations. Vert.x came up with own implementations for various databases and provides APIs that work well in a Vert.x context but these APIs are not JDBC.

Relational Database APIs

As M-Razavi already mentioned, Java uses JDBC to integrate with relational databases and JDBC is of a blocking nature – there's nothing sensible one could do about to mitigate the blocking nature of JDBC. Offloading JDBC calls to an Executor (typically Thread pool) is limited in its usefulness as the pool eventually saturates with requests). TL;DR, there's no API available on top of which we could provide a reactive relational database integration.

So what are the options?

M-Razavi already mentioned ADBA that is an initiative from Oracle to provide a standardized API for asynchronous database access in Java using futures. Everything in ADBA is still work in progress and the team behind ADBA is happy to get feedback. A bunch of Postgres folks is working on a Postgres ADBA driver that can be used for first experiments.

However, ADBA is a future goal and I expect that we don't see ADBA released with Java 12.

There are a couple of independent drivers such as Reactiverse's reactive-pg-client. These drivers come with a vendor-specific API and aren't really suited for a broader integration in Spring. We would need to provide additional layers to expose a common API, and new drivers couldn't be just plugged into your application so it works-out-of-the-box™. Having a standard API allows pluggability, so there's huge value in having a standard API.

R2DBC to the rescue?

Lacking a standard API and the non-availability of drivers, a team at Pivotal started to investigate on a reactive relational API that would be an ideal fit for reactive programming purposes. They came up with R2DBC which stands for Reactive Relational Database Connectivity. As of now, R2DBC is an incubator project to evaluate the feasibility and to start discussions whether driver vendors are interested at all in supporting reactive/non-blocking/asynchronous drivers.

As of now, there are three driver implementations:

  • PostgreSQL
  • H2
  • Microsoft SQL Server

R2DBC comes with an API specification (r2dbc-spi) and a client (r2dbc-client) that makes the SPI usable for applications. We started exploring on a Spring Data R2DBC integration that provides reactive APIs through a database client and by supporting reactive repositories.

R2DBC and its eco-system are still young and ask for experiments and feedback to collect use cases and to see whether a reactive relational database integration would make sense.

Right now, you can consume R2DBC through Spring Data and the following snippet shows DatabaseClient usage:

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();



回答2:


Spring WebFlux is a great way to create a non-blocking REST application. One issue that you run into when start working with WebFlux is JDBC, because JDBC is blocking. New school databases like Cassandra or Couchbase have non-blocking drivers. In Couchbase’s case its driver uses RXJava. There is some effort going into creating asynchronous drivers for databases, as well as Oracle’s effort to create ADBA. Unfortunately, these are early days, and if you want to talk to a SQL database on the JVM you’re stuck with a blocking driver.
Actually, Spring is not responsible for providing a none blocking driver for relational databases.



来源:https://stackoverflow.com/questions/53244964/why-does-spring-not-provide-reactive-non-blocking-clients-for-relational-datab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!