内容简介:Reactive Programming可以看作是一种编程模型,它通过创建事件驱动的非阻塞功能管道来促进可扩展性和稳定性,这些管道对资源的可用性和可处理性做出反应。延迟执行,只有当整个堆栈都是被动的并且所有参与的组件(应用程序代码,运行时容器,集成)都遵循延迟执行,非阻塞API和数据流的流式特性时,响应式编程的全部好处才会生效 - 基本上遵循基本假设。虽然可以将非反应性组件引入以函数响应式编写的应用程序,但最终结果是对可扩展性和稳定性影响,实际预期收益减少。在最坏的情况下,运行时行为很少或没有区别。但是,
Reactive Programming可以看作是一种编程模型,它通过创建事件驱动的非阻塞功能管道来促进可扩展性和稳定性,这些管道对资源的可用性和可处理性做出反应。延迟执行, 并发和异步性 只是底层编程模型的结果。
只有当整个堆栈都是被动的并且所有参与的组件(应用程序代码,运行时容器,集成)都遵循延迟执行,非阻塞API和数据流的流式特性时,响应式编程的全部好处才会生效 - 基本上遵循基本假设。
虽然可以将非反应性组件引入以函数响应式编写的应用程序,但最终结果是对可扩展性和稳定性影响,实际预期收益减少。在最坏的情况下,运行时行为很少或没有区别。但是,响应式编程有助于提高代码的可读性。
如果我们查看响应式生态系统,我们将发现几个框架,库和集成。他们每个人都有自己的特长。通过通用方法或在特定响应框架的上下文中,可以很好地涵盖许多功能领域。我们来讨论关系数据库集成。
最常见的问题是:我们什么时候可以使用API进行响应性关系数据库集成?
Java使用JDBC作为与关系数据库集成的主要技术。JDBC具有阻塞性 - 没有什么可以减轻JDBC的阻塞性质。关于如何使调用无阻塞的第一个想法是将JDBC调用卸载到Executor(通常是Thread池)。虽然这种方法有些作用,但它有几个缺点,忽略了响应式编程模型的好处。
响应运行时通常使用与CPU核心数匹配的有限数量的线程。额外的线程引入开销并减少线程限制的影响。此外,JDBC调用通常会堆积在队列中,一旦线程充满请求,池将再次阻塞。所以,JDBC现在不是唯一一个选择。
响应式数据库API
Oracle宣布推出 ADBA ,该计划旨在通过使用期货为 Java 中的异步数据库访问提供标准化API。Postgres正在研究可用于第一次实验的 Postgres ADBA驱动程序 。 PgNio 是Postgres的另一个异步驱动程序,它开始尝试使用ADBA。
ADBA的可用性未知。它绝对不会在Java 12的版本中可使用,ADBA计划首次亮相的Java版本目前尚不清楚。
以下代码段显示了使用INSERT和SELECT语句的ADBA :
DataSource ds = dataSource(); CompletableFuture<Long> t; try (Session session = ds.getSession()) { Submission<Long> submit = session .<Long>rowCountOperation( "INSERT INTO legoset (id, name, manual) " + "VALUES($1, $2, $3)") .set("$1", 42055, AdbaType.INTEGER) .set("$2", "Description", AdbaType.VARCHAR) .set("$3", null, AdbaType.INTEGER) .apply(Result.RowCount::getCount) .submit(); t = submit.getCompletionStage().toCompletableFuture(); } t.join(); CompletableFuture<List<Map<String, Object>>> t; try (Session session = ds.getSession()) { Submission<List<Map<String, Object>>> submit = session .<List<Map<String, Object>>> rowOperation( "SELECT id, name, manual FROM legoset") .collect(collectToMap()) // custom collector .submit(); t = submit.getCompletionStage().toCompletableFuture(); } t.join();
请注意,这collectToMap(…)是应用程序提供的函数的示例,该函数将结果提取到所需的返回类型。
R2DBC
由于缺乏标准API和驱动程序不可用, Pivotal 的团队开始研究反应性关系API的想法,该API非常适合用于反应式编程。他们提出了 R2DBC ,它代表了Reactive Relational Database Connectivity。截至目前,R2DBC是一个孵化器项目,用于评估可行性并开始讨论驱动程序供应商是否有兴趣支持反应/非阻塞/异步驱动程序。
截至目前,有三种驱动程序实现:
R2DBC附带API规范(r2dbc-spi)和客户端(r2dbc-client),使SPI可用于应用程序。
以下代码段显示R2DBC SPI使用INSERT和SELECT语句:
ConnectionFactory connectionFactory = null; Mono<Integer> count = Mono.from(connectionFactory.create()) .flatMapMany(it -> it.createStatement( "INSERT INTO legoset (id, name, manual) " + "VALUES($1, $2, $3)") .bind("$1", 42055) .bind("$2", "Description") .bindNull("$3", Integer.class) .execute()) .flatMap(io.r2dbc.spi.Result::getRowsUpdated) .next(); Flux<Map<String, Object>> rows = Mono.from(connectionFactory.create()) .flatMapMany(it -> it.createStatement( "SELECT id, name, manual FROM legoset").execute()) .flatMap(it -> it.map((row, rowMetadata) -> collectToMap(row, rowMetadata)));
虽然上面的代码有点笨重,但R2DBC还附带了一个客户端库项目,用于更人性化的用户API。R2DBC SPI不用于直接使用,而是通过客户端库使用。
使用R2DBC客户端重写的相同代码将是:
R2dbc r2dbc = new R2dbc(connectionFactory); Flux<Integer> count = r2dbc.inTransaction(handle -> handle.createQuery( "INSERT INTO legoset (id, name, manual) " + "VALUES($1, $2, $3)") .bind("$1", 42055) .bind("$2", "Description") .bindNull("$3", Integer.class) .mapResult(io.r2dbc.spi.Result::getRowsUpdated)); Flux<Map<String, Object>> rows = r2dbc .inTransaction(handle -> handle.select( "SELECT id, name, manual FROM legoset") .mapRow((row, rowMetadata) -> collectToMap(row, rowMetadata));
请注意,collectToMap(…)作为应用程序提供的函数的示例,该函数将结果提取到所需的返回类型。
Spring Data团队将 Spring Data R2DBC 作为孵化器启动,通过数据库客户端提供响应API并支持反应式存储库。使用Spring Data R2DBC重写的示例代码将是:
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();
R2DBC及其生态系统仍然很年轻,并要求进行实验和反馈以收集用例,并查看反应性关系数据库集成是否有意义。
Fibers的JDBC
虽然JDBC和其他技术暴露了阻塞API(主要是由于等待I / O),但 Project Loom 引入Fibers了轻量级抽象,将阻塞API转变为非阻塞API。一旦调用遇到阻塞API,就可以通过堆栈切换实现这一点。因此Fiber,继续使用阻塞API的先前流程的基础尝试。
该Fiber执行模式大大减少了所需的原生线程数。结果是更好的可伸缩性和非阻塞行为 - 通过卸载对Fiber-backed的阻塞调用Executor。我们所需要的只是一个适当的API,允许在Fiber实现上使用非阻塞JDBC 。
结论
反应式编程和关系数据库的未来是什么?老实说,我不知道。如果我尝试了一个有根据的猜测,我可以看到Project Loom和它的基于Fiber的Executor与成熟的JDBC驱动程序相结合,成为业界潜在的游戏规则改变者。随着Java的加速发布节奏,这可能并不遥远。
ADBA的目标是包含在Java标准版运行时中,根据当前的时间表,我预计它将在早于2021年的Java 17中出现。
与现在可用的R2DBC形成对比。它配备了驱动程序和客户端,并允许实验使用。R2DBC的一个简洁的副作用是它暴露完全反应的API,同时独立于底层数据库引擎。随着已经发布的版本,没有必要猜测Project Loom,也不需要等待三年才能测试其驱动API。今天就可以使用R2DBC。
以上所述就是小编给大家介绍的《使用R2DBC实现数据库的响应式访问》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 响应式布局的实现
- VueJS 响应式原理及简单实现
- Bootstrap禁用响应式布局的实现方法
- jQuery实现鼠标响应式淘宝动画效果示例
- Pike:5 分钟实现接口 10 倍响应提升
- Vue 进阶系列之响应式原理及实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ajax设计模式
Michael Mahemoff / 杨仁和 / 电子工业出版社 / 2007-5 / 78.00元
★本书荣获LinuxWorld Linux Journal2006年Editors' Choice awards。 ★绝好的一本ajax 高级读物,建议 每个web 程序员都需要买一本,了解什么是真正的好的web设计--网友 [精彩试读一] [精彩试读二] 本书是一本关于复杂Ajax应用的整体架构设计......一起来看看 《Ajax设计模式》 这本书的介绍吧!