当前位置: 首页 > 面试题库 >

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

黄朗
2023-03-14
问题内容

我已经使用Vert.x工具包来创建反应性应用程序,并支持MySQL和Postgres等关系数据库。我知道Spring为某些NoSQL数据库(例如Cassandra和Mongo)提供了响应式支持,但他们愿意为关系数据库提供相同的支持吗?


问题答案:

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

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

WebFlux与Vert.x的比较

Spring WebFlux是典型的Spring模块的一个很好的例子。它基于现有的非阻塞服务器(通过netty,Undertow和Jetty的Project
Reactor)之上。WebFlux为利用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,我们可以在其上提供反应性关系数据库集成。

那有什么选择呢?

M-Razavi]已经提到了ADBA,这是Oracle的一项举措,旨在为使用期货的Java中的异步数据库访问提供标准化的API。ADBA中的所有内容仍在进行中,ADBA背后的团队很高兴获得反馈。一群Postgres人员正在研究可用于首次实验的Postgres
ADBA驱动程序。

但是,ADBA是未来的目标,我希望我们不会看到ADBA与Java 12一起发布。

有几个独立的驱动程序,例如Reactiverse的react-pg-
client。这些驱动程序带有特定于供应商的API,并不真正适合于Spring中的更广泛的集成。我们将需要提供更多的层来公开通用的API,并且不能将新的驱动程序仅插入到您的应用程序中,因此它可以即开即用地运行。拥有标准API可以实现可插入性,因此拥有标准API具有巨大的价值。

R2DBC可以救援吗?

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

到目前为止,有三种驱动程序实现:

  • PostgreSQL的
  • H2
  • Microsoft SQL服务器

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

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

现在,您可以通过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();


 类似资料:
  • 如何为不支持流式处理的数据库提供反应式流 API?比如说dymodb。执行 get 调用时,dynamodb 将返回所有结果。因此,即使我将 get 调用包装在源中,如何处理来自下游阶段的背压?另外,如何实现写入 db 中的写入调用?我的水槽会是什么样子?任何关于此的指针都会有所帮助。

  • 我希望客户不会等待4秒然后得到实际的结果。如您所见,服务器在22:44:21.126上开始发出onNext(),客户端在22:44:24.159上获得结果。所以我不明白如果webclient有这种行为,为什么它被称为非阻塞客户端。

  • 问题内容: 我想编写一个可以同时写入多个文件的程序。认为可以通过使用非阻塞模式在一个线程中实现。但是FileChannel不支持非阻塞模式。有人知道为什么吗? 问题答案: UNIX不支持非阻塞的文件I / O,看到非阻塞I / O与常规文件 。由于Java应该(至少尝试在所有平台上)提供相同的行为,因此不会实现。 但是,Java 7将包括一个支持 异步 文件I / O 的新类,这是与非阻塞I /

  • 我正在尝试通过对象读取命令。为了检查输入语法,我使用<code>sc。hasNext()(对于缺少命令的情况)。它已经在很多情况下运行良好,但现在我看到了JavaAPI中描述的“MAY block and wait for Input”的情况。 方法何时阻塞,我如何控制它?有趣的是,在街区前的3个案例中,它工作得非常好。此外,JavaAPI还将描述为检查是否存在另一个Input的正确方法,从而使方

  • 问题内容: 注意:这不是有关settimeout的复制文章,此处的关键答案是浏览器设计选项。 我开始研究node.js:一个测试异步的简单示例: 一件有趣的事情是,在带有curl的lind命令和浏览器中,它的行为是不同的:在Ubuntu 12.10中,我在两个控制台中使用curl localhost:8080,它们在几乎相同的10个发送中进行响应。 但是,我打开了两个浏览器,几乎同时发出了请求,但

  • 我不明白以下几点: 用户级线程需要非阻塞系统调用,即多线程内核。否则,整个进程将在内核中阻塞,即使进程中还有可运行的线程。 内核线程如何处理阻塞系统调用?在用户级线程中,当一个线程进行阻塞系统调用(例如读取)时,为什么其他线程不能继续工作?