java - 为什么 Spring 不为关系数据库提供响应式(Reactive)(非阻塞)客户端?

标签 java spring-data spring-webflux reactive r2dbc

我用过 Vert.x用于创建响应式应用程序的工具包,支持关系数据库,如 MySQL and Postgres .我知道 Spring 为 Cassandra 和 Mongo 等一些 NoSQL DB 提供响应式(Reactive)支持,但他们愿意为关系 DB 提供相同的支持吗?

最佳答案

Spring 框架背后的想法是什么?

Spring Framework 是一个提高开发人员生产力的库,Spring Data、Spring Security、Spring Cloud 等 Spring 的投资组合项目也是如此。

这些项目建立在现有 API 之上,这些 API 要么通过 JSR 或 JEP 标准化,要么建立在已被证明有用且广泛使用的库之上。 Spring 团队不会为数据库或其他集成构建驱动程序,这取决于数据库/驱动程序供应商。

WebFlux 与 Vert.x 相比

Spring WebFlux 是典型 Spring 模块的一个很好的例子。它建立在现有的非阻塞服务器(通过 netty、Undertow 和 Jetty 的 Project Reactor)之上。 WebFlux 为非阻塞、响应式(Reactive)应用程序提供了一个运行时容器,利用 Spring 组件来帮助开发和运行此类应用程序。

Vert.x 是集成环境的一个很好的例子,它提供了自己的低级实现。 Vert.x 进行了大量优化,这样的生态系统需要优化集成。 Vert.x 为各种数据库提出了自己的实现,并提供了在 Vert.x 上下文中运行良好的 API,但这些 API 不是 JDBC。

关系数据库 API

M-Razavi已经提到过,Java 使用 JDBC 与关系数据库集成,而 JDBC 具有阻塞性质——没有任何明智的方法可以减轻 JDBC 的阻塞性质。将 JDBC 调用卸载到 Executor (通常是 Thread 池)的用途有限,因为池最终会因请求而饱和)。 TL;DR,没有可用的 API,我们可以在其上提供响应式(Reactive)关系数据库集成。

那么有哪些选择呢?

M-Razavi已经提到 ADBA这是 Oracle 的一项举措,旨在为使用 future 的 Java 异步数据库访问提供标准化 API。 ADBA 中的一切仍在进行中,ADBA 背后的团队很高兴获得反馈。一群 Postgres 人员正在开发 Postgres ADBA driver可用于第一次实验。

然而,ADBA 是一个 future 的目标,我希望我们不会看到 ADBA 随 Java 12 一起发布。

有几个独立的驱动程序,例如 Reactiverse's reactive-pg-client .这些驱动程序带有特定于供应商的 API,并不真正适合在 Spring 中进行更广泛的集成。我们需要提供额外的层来公开一个公共(public) API,并且新的驱动程序不能只是插入到您的应用程序中,所以它可以开箱即用™。拥有标准 API 可以实现可插拔性,因此拥有标准 API 具有巨大的值(value)。

R2DBC 来救援?

缺乏标准 API 和驱动程序不可用,团队位于 Pivotal开始研究一种非常适合响应式(Reactive)编程目的的响应式(Reactive)关系 API。他们想出了R2DBC它代表响应式(Reactive)关系数据库连接。到目前为止,R2DBC 是一个孵化器项目,用于评估可行性并开始讨论驱动程序供应商是否对支持响应式(Reactive)/非阻塞/异步驱动程序感兴趣。

截至目前,共有三种驱动程序实现:

  • PostgreSQL
  • H2
  • Microsoft SQL Server

  • R2DBC 带有 API 规范 ( r2dbc-spi ) 和客户端 ( r2dbc-client ),使 SPI 可用于应用程序。我们开始探索 Spring Data R2DBC通过数据库客户端和支持响应式(Reactive)存储库提供响应式(Reactive) API 的集成。

    R2DBC 及其生态系统还很年轻,需要进行实验和反馈以收集用例并查看响应式(Reactive)关系数据库集成是否有意义。

    现在,您可以通过 Spring Data 使用 R2DBC,以下代码片段显示 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();
    

    关于java - 为什么 Spring 不为关系数据库提供响应式(Reactive)(非阻塞)客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53244964/

    相关文章:

    java - 如何渲染无间隙的逐像素绘图? Java Swing

    java - 为什么 ConcurrentSkipListSet 升序迭代器 'faster' 而不是降序迭代器?

    java - 如何在@Transactional 方法中手动强制提交?

    java - 如何等待多个 WebClient Flux 请求完成?

    java - 写 cucumber 故事时有哪些准则?

    java - 无法插入 MS Access 数据库

    java - 如何在 Gemfire 区域创建复合主键场景?

    Java Couchbase JsonArray 不支持的类型

    java - 将 RxJava Single 转换为 Mono

    java - 使用 mongo 响应式(Reactive) Spring 检查 Webflux 数据