Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reactive Relational Database Connectivity 2020

Mark Paluch
November 28, 2019

Reactive Relational Database Connectivity 2020

Summarizes the state of R2DBC in 2020

Mark Paluch

November 28, 2019
Tweet

More Decks by Mark Paluch

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

  3. 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

    View Slide

  4. 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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. 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()

    View Slide

  12. 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)

    View Slide

  13. 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()

    View Slide

  14. 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);

    View Slide

  15. 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))))

    View Slide

  16. 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))))

    View Slide

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

    View Slide

  18. 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)))

    View Slide

  19. 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())

    View Slide

  20. 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())

    View Slide

  21. 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

    View Slide

  22. 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();

    View Slide

  23. 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))

    View Slide

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

    View Slide

  25. 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

    View Slide

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

    View Slide

  27. 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

    View Slide

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

    View Slide

  29. 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();
    }

    View Slide

  30. 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();

    View Slide

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

    View Slide

  32. 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


    View Slide

  33. 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


    View Slide

  34. 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");

    View Slide

  35. 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

    View Slide

  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/
    36

    View Slide

  37. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  42. 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!

    View Slide

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

    View Slide

  44. 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

    View Slide

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

    View Slide

  46. Thank you.
    r2dbc.io
    @mp911de

    View Slide