Summarizes the state of R2DBC in 2020
Reactive Relational DatabaseConnectivityMark Paluch • Spring Data Project Lead, R2DBC Contributor • @mp911de
View Slide
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Reactive Programming● High-efficiency applications● Fundamentally non-blocking● No opinion on async● Key differentiators: (pull-push) back pressure, flow control2
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/SubscriberPublisherSubscribeDataDemand
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/SubscriberPublisherSubscribeDatarequest(n)
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/WebFlux and WebClient5@GetMapping("/health")Mono compositeHealth() {return Mono.zip(webClient.get().uri("https://alpha-service/health").retrieve().bodyToMono(Health.class),webClient.get().uri("https://bravo-service/health").retrieve().bodyToMono(Health.class)).map(t -> composite(t.getT1(), t.getT2()));}
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Roadblocks● Barriers to using Reactive everywhere● Data Access● MongoDB, Apache Cassandra, Redis● No Relational Database Access6
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/7A specification designed from theground up for reactive programminghttps://r2dbc.io
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Dependencies● Reactive Streams● Java 88
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Design Principles● Embrace Reactive Types and Patterns● Non-blocking, all the way to the database● Documented specification● Shrink the driver SPI● Enable multiple "humane" APIs9
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Driver SPI● JDBC: same API for humane API and inhumane SPI for alternative clientslike JPA, jOOQ, Jdbi, etc.● API that users didn't like using and driver authors didn't likeimplementing● Duplicating effort implementing the same "humane" affordances like ?binding10
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Driver SPI: ConnectionFactory11Publisher create()ConnectionFactoryMetadata getMetadata()
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Driver SPI: Connection12Publisher beginTransaction()Publisher close()Publisher commitTransaction()Batch createBatch()Publisher createSavepoint(String name)Statement createStatement(String sql)Publisher releaseSavepoint(String name)Publisher rollbackTransaction()Publisher rollbackTransactionToSavepoint(String name)Publisher setTransactionIsolationLevel(IsolationLevel isolationLevel)
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Driver SPI: Statement13Statement add()Statement bind(String name, Object value)Statement bind(int index, Object value)Statement bindNull(String name, Class> type)Statement bindNull(int index, Class> type)Statement returnGeneratedValues(String… columnNames)Publisher execute()
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Driver SPI: Result and Row14Publisher getRowsUpdated()Publisher map(BiFunction f)T get(String identifier, Class type);Object get(String identifier);T get(int index, Class type);Object get(int index);
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Simple Select15Publisher values = connectionFactory.create().flatMapMany(conn ->conn.createStatement("SELECT value FROM test").execute().flatMap(result ->result.map((row, metadata) -> row.get("value", String.class))))
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Transactional Update16Publisher results = connectionFactory.create().flatMapMany(conn ->conn.beginTransaction().thenMany(conn.createStatement("INSERT INTO test VALUES($1)").bind("$1", 100).add().bind("$1", 200).execute()).delayUntil(p -> conn.commitTransaction()).onErrorResume(t ->conn.rollbackTransaction().then(Mono.error(t))))
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Great! But a Bit Verbose.● Minimal set of implementation specific operations● Definitely usable, but very verbose and prone to errors● Explicit transaction management is analogous to try-catch-finally-try-catch in JDBC● We need a "humane" client API. In fact we need many humane clientAPIs!17
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/R2DBC Client18Flux values = r2dbc.withHandle(handle ->handle.select("SELECT value FROM test").mapRow(row -> row.get("value", String.class)))
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Parametrized Statement19Flux updatedRows = r2dbc.withHandle(handle ->handle.createUpdate("INSERT INTO test VALUES($1, $2)").bind("$1", 100).bind("$2", 200).add().bind("$1", 300).bind("$2", 400).execute())
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Transactional Update20Flux updatedRows = r2dbc.inTransaction(handle ->handle.createUpdate("INSERT INTO test VALUES($1, $2)").bind("$1", 100).bind("$2", 200).add().bind("$1", 300).bind("$2", 400).execute())
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Spring Data R2DBC
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Spring Data R2DBC22DatabaseClient client = DatabaseClient.create(connectionFactory);Flux rows = client.execute("SELECT * FROM person WHERE name = :name").bind("name", "John Doe").as(Person.class).fetch().all();
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/R2DBC Repositories23interface CustomerRepository extendsReactiveCrudRepository {@Query("SELECT * FROM … WHERE lastname = :lastname")Flux findByLastname(String lastname);}repository.findByLastname("Matthews").doOnEach(c -> System.out.println(c.firstname))
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Spring Data R2DBC● Functional-reactive declaration of data access● Fluent API● Support for Transactions● Named parameter support (Dialect-aware)● Repositories● Kotlin Coroutines extensions24
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Demo
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Atomic Operations● Application and Database transactions● Classic implementations Thread-bound26
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Reactive Transactions● Application and Database transactions● Pattern is still correct27
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Reactive Transactions● Application and Database transactions● Pattern is still correct● Bind transactional state to Subscription● Reactor Context28
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Reactive Transactions29PersonRepository people;AddressRepository addresses;@TransactionalMono savePerson(Person person, Address address) {return people.save(person).then(addresses.save(address)).then();}
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Programmatic Reactive Transactions30PersonRepository people;AddressRepository addresses;R2dbcTransactionManager txManager;TransactionalOperator rxtx = TransactionalOperator.create(txManager);Mono saved = people.save(person).then(addresses.save(address)).as(rxtx::transactional).then();
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Getting Started with R2DBC● Available from Maven Central● start.spring.io31
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Getting Started with R2DBC32io.r2dbcr2dbc-bomArabba-SR2pomimportio.r2dbcr2dbc-h2
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Getting Started with R2DBC33io.r2dbcr2dbc-bomArabba-SR2pomimportio.r2dbcr2dbc-h2
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/R2DBC Connection URL34r2dbc:pool:postgresql://localhost:5432/database?key=valueConnectionFactory connectionFactory =ConnectionFactories.get("r2dbc:postgresql://myhost/database?driver=foo");
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Spring Boot Starter for R2DBC● ConnectionFactory configuration● R2DBC TransactionManager● Embedded H2 support● Actuator integration● Schema.sql and Data.sql support● @DataR2dbcTest35
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/36
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/R2DBC Ecosystem
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/R2DBC Ecosystem● Specification document● R2DBC SPI● R2DBC Proxy● Connection Pooling● Client Implementations● Spring Data R2DBC● r2dbc-client● Kotysa● Drivers● Google Cloud Spanner● H2● Microsoft SQL Server● MySQL Driver (r2dbc-mysql,jasync-sql)● MariaDB● PostgreSQL● SAP Hana38
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Planned R2DBC Clients● MyBatis (#1444)● JDBI (#1454)● jOOQ (#6298)● Querydsl (#2468)● Helidon (#581)● Liquibase (CORE-3419)● Flyway (#2502)● Exposed (#456)● Testcontainers (#1003)● Go vote for a client you want to see happen.39
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Planned R2DBC Drivers● MariaDB (alpha-state by MariaDB Inc.)● Firebird (Jaybird) investigating● Oracle investigating● DB2 foundation in the works (started with a vert.x driver first)● Ask your vendor!40
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Non-blocking SQL Database Endeavours● Various individual driver projects (NDBC, Jasync, Vert.x, …)● Hibernate Rx● ADBA: Asynchronous Database API● OJDBC 20 with Reactive Extensions● Oracle looking into R2DBC41
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Wrap up!
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/What Can You Do Today?● End-to-end reactive non-blocking database communication● Batching● BLOB/CLOB● Extensive Type Conversion● Savepoints● Transactions● Leveraging Database-specific features● ServiceLoader-based Driver discovery● Connection URLs● Categorized exceptions (Bad grammar, Data integrity violation, …)43
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/R2DBC Roadmap● Started as experiment in early 2018● Available as 0.8.0 SR2● 0.9.0: Stored Procedures, Extended transaction spec, EventProvider44
Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/Resources● Website https://r2dbc.io● Twitter @r2dbc● GitHub https://github.com/r2dbc● Mailing List https://groups.google.com/forum/#!forum/r2dbc● Monthly Call 1st Friday of Month 0630 PT/0930 ET/1530 CET45
Thank you.r2dbc.io@mp911de