Slide 1

Slide 1 text

Reactive Relational Database Connectivity Mark Paluch • Spring Data Project Lead, R2DBC Contributor • @mp911de

Slide 2

Slide 2 text

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 control 2

Slide 3

Slide 3 text

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/ Subscriber Publisher Subscribe Data Demand

Slide 4

Slide 4 text

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/ Subscriber Publisher Subscribe Data request(n)

Slide 5

Slide 5 text

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 WebClient 5 @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())); }

Slide 6

Slide 6 text

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 Access 6

Slide 7

Slide 7 text

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/ 7 A specification designed from the ground up for reactive programming https://r2dbc.io

Slide 8

Slide 8 text

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 8 8

Slide 9

Slide 9 text

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" APIs 9

Slide 10

Slide 10 text

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 clients like JPA, jOOQ, Jdbi, etc. ● API that users didn't like using and driver authors didn't like implementing ● Duplicating effort implementing the same "humane" affordances like ? binding 10

Slide 11

Slide 11 text

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: ConnectionFactory 11 Publisher create() ConnectionFactoryMetadata getMetadata()

Slide 12

Slide 12 text

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: Connection 12 Publisher 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)

Slide 13

Slide 13 text

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: Statement 13 Statement 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()

Slide 14

Slide 14 text

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 Row 14 Publisher 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);

Slide 15

Slide 15 text

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 Select 15 Publisher values = connectionFactory.create() .flatMapMany(conn -> conn.createStatement("SELECT value FROM test") .execute() .flatMap(result -> result.map((row, metadata) -> row.get("value", 
 String.class))))

Slide 16

Slide 16 text

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 Update 16 Publisher 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))))

Slide 17

Slide 17 text

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 client APIs! 17

Slide 18

Slide 18 text

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 Client 18 Flux values = r2dbc.withHandle(handle -> handle.select("SELECT value FROM test") .mapRow(row -> row.get("value", String.class)))

Slide 19

Slide 19 text

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 Statement 19 Flux 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())

Slide 20

Slide 20 text

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 Update 20 Flux 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())

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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 22 DatabaseClient client = DatabaseClient.create(connectionFactory); Flux rows = client .execute("SELECT * FROM person WHERE name = :name") .bind("name", "John Doe") .as(Person.class) .fetch() .all();

Slide 23

Slide 23 text

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 Repositories 23 interface CustomerRepository extends ReactiveCrudRepository { @Query("SELECT * FROM … WHERE lastname = :lastname") Flux findByLastname(String lastname); } repository.findByLastname("Matthews") .doOnEach(c -> System.out.println(c.firstname))

Slide 24

Slide 24 text

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 extensions 24

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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-bound 26

Slide 27

Slide 27 text

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 27

Slide 28

Slide 28 text

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 Context 28

Slide 29

Slide 29 text

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 29 PersonRepository people; AddressRepository addresses; @Transactional Mono savePerson(Person person, Address address) { return people.save(person) .then(addresses.save(address)).then(); }

Slide 30

Slide 30 text

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 Transactions 30 PersonRepository people; AddressRepository addresses; R2dbcTransactionManager txManager; TransactionalOperator rxtx = TransactionalOperator.create(txManager); Mono saved = people.save(person) .then(addresses.save(address)) .as(rxtx::transactional).then();

Slide 31

Slide 31 text

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.io 31

Slide 32

Slide 32 text

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 32 io.r2dbc r2dbc-bom Arabba-SR2 pom import io.r2dbc r2dbc-h2

Slide 33

Slide 33 text

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 33 io.r2dbc r2dbc-bom Arabba-SR2 pom import io.r2dbc r2dbc-h2

Slide 34

Slide 34 text

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 URL 34 r2dbc:pool:postgresql://localhost:5432/database?key=value ConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:postgresql://myhost/database? driver=foo");

Slide 35

Slide 35 text

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 ● @DataR2dbcTest 35

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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 Hana 38

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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 R2DBC 41

Slide 42

Slide 42 text

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!

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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, EventProvider 44

Slide 45

Slide 45 text

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 CET 45

Slide 46

Slide 46 text

Thank you. r2dbc.io @mp911de