Slide 1

Slide 1 text

@mp911de and @rotnroll666 #Devoxx #ReactiveProgramming Reactive transaction masterclass Mark Paluch, Pivotal. Michael Simons, Neo4j, Inc.

Slide 2

Slide 2 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Mark Paluch • Spring Data Project Lead • Lettuce Redis Driver Project Lead • R2DBC Contributor • All things Reactive Data & Open Source github.com/mp911de • @mp911de • paluch.biz

Slide 3

Slide 3 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Michael Simons • Neo4j since July 2018 • Java Champion and Oracle Groundbreaker • Co-Founder and current lead of Java User Group EuregJUG • Author

Slide 4

Slide 4 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 More books: Life behind bars • I run… • I bike… • …and take pictures Revenue will go to Médecins Sans Frontières msf.org this year https://leanpub.com/lifebehindbars

Slide 5

Slide 5 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Imperative Transactions

Slide 6

Slide 6 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Regular transaction

Slide 7

Slide 7 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 8

Slide 8 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 9

Slide 9 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 [ ]

Slide 10

Slide 10 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 [ ]

Slide 11

Slide 11 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 12

Slide 12 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 13

Slide 13 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Phantom read

Slide 14

Slide 14 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 15

Slide 15 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 16

Slide 16 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 17

Slide 17 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 18

Slide 18 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 19

Slide 19 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 20

Slide 20 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 21

Slide 21 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 22

Slide 22 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 23

Slide 23 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 24

Slide 24 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 25

Slide 25 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 26

Slide 26 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 27

Slide 27 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 28

Slide 28 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 No rollback / Duplication

Slide 29

Slide 29 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 30

Slide 30 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 31

Slide 31 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 32

Slide 32 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 33

Slide 33 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 34

Slide 34 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Broken transaction

Slide 35

Slide 35 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 36

Slide 36 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 37

Slide 37 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 38

Slide 38 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 39

Slide 39 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 40

Slide 40 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 41

Slide 41 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 42

Slide 42 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 43

Slide 43 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 44

Slide 44 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Transaction • Atomically apply changes • Isolation • Consistency • Durable • Require a transactional resource

Slide 45

Slide 45 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Resource-local Transaction • Allocate transactional resource • Apply work • Cleanup transaction

Slide 46

Slide 46 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Database Example • Open connection • Begin transaction • Apply work • Reuse same connection across operations • Commit/rollback transaction

Slide 47

Slide 47 text

Demo #Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 48

Slide 48 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Transaction Attributes • Isolation Level • Explicit Commit Mode • Read-Only Optimizations

Slide 49

Slide 49 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Transaction Management • Ensures transactional behaviour • Apply transaction definition (propagation, attributes) • Implementations • JTA • Spring • Driver-specific

Slide 50

Slide 50 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Transaction Managers •DataSourceTransactionManager •MongoTransactionManager •Neo4jTransactionManager

Slide 51

Slide 51 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Transaction Walkthrough • Allocate connection • Bind connection to transaction (Thread*) • Prepare connection for transaction (isolation level, …) • Issue queries (Reuse bound connection) • Exit transactional scope • Cleanup, commit or rollback • Run synchronizations • Unbind resources

Slide 52

Slide 52 text

Demo #Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Transactional

Slide 53

Slide 53 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Bound connection • Transactional state associated with transport connection • Works since the ’70s like that • Alternatively: Session • Newer implementations: Portable session • MongoDB

Slide 54

Slide 54 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Imperative Transactions • Stay on a single thread* • ThreadLocal storage • Using another thread breaks transactions * ManagedExecutorService, @Async

Slide 55

Slide 55 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Imperative transactions are fully synchronous

Slide 56

Slide 56 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Time-dependency in transactions

Slide 57

Slide 57 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Time dependency • Begin Tx before work • Work after begin Tx • Work before cleanup Tx • Cleanup Tx after work

Slide 58

Slide 58 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Distributed Transactions

Slide 59

Slide 59 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 60

Slide 60 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Distributed Transactions • XA specification • Released in the 90’s • Transactions across distributed services • Two phase commit • Turned out that it sucks

Slide 61

Slide 61 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Still Distributed Transactions • Redis + JDBC Transaction • Kind-of works • Leading transaction manager • Additional transactional resources may join • Independent commit/rollback • Still sucks

Slide 62

Slide 62 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Reactive Transactions

Slide 63

Slide 63 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Database • Open connection • Begin transaction • Apply work • Reuse same connection across operations • Commit/rollback transaction

Slide 64

Slide 64 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Transaction Managers •R2dbcTransactionManager •Neo4jTransactionManager •MongoTransactionManager

Slide 65

Slide 65 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Transaction Walkthrough • Allocate connection • Bind connection to transaction (Subscription) • Prepare connection for transaction (isolation level, …) • Issue queries (Reuse bound connection) • Exit transactional scope • Cleanup, commit or rollback • Run synchronizations • Unbind resources

Slide 66

Slide 66 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Reactive transactions are fully synchronous

Slide 67

Slide 67 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Reactive transactions are non-blocking

Slide 68

Slide 68 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Time-dependency in transactions

Slide 69

Slide 69 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Time dependency • Begin before work • Work after begin • Work before cleanup • Cleanup after work

Slide 70

Slide 70 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Imperative vs. Reactive • Single-threaded processing required • ThreadLocal transaction status • Data stays within transactional bounds • Synchronized begin and cleanup • Multi-threaded processing possible • Subscription-bound transaction status • Data escapes transactional bounds • Synchronized begin and cleanup

Slide 71

Slide 71 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Cancelation (Connection Terminated while Processing)

Slide 72

Slide 72 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 73

Slide 73 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) (Server)

Slide 74

Slide 74 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server)

Slide 75

Slide 75 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server)

Slide 76

Slide 76 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server)

Slide 77

Slide 77 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server)

Slide 78

Slide 78 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server) ✂

Slide 79

Slide 79 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server) ✂

Slide 80

Slide 80 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server) ✂

Slide 81

Slide 81 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server)

Slide 82

Slide 82 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server)

Slide 83

Slide 83 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 (Client) POST /some/data (Server)

Slide 84

Slide 84 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 More on cancelation

Slide 85

Slide 85 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Cancellation • .first(), .take(n) • Send cancellation signal upstream • „Thank you I don’t need additional data“ • „Connection dead. Cancelling“

Slide 86

Slide 86 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Cancellation effects • Cancellation considered success • Cancelled subscription does not await completion • Commit may be not yet visible to subsequent operations

Slide 87

Slide 87 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 // Define a flow that creates 1000 nodes in a database Flux createNodes = Flux.using( driver::rxSession, session -> session.run( "UNWIND range (1,1000) AS i CREATE (s:SomeNode {pos: i}) return s").records(), RxSession::close ).map(r -> r.get("s").get("pos").asInt()); „Cancelled subscription does not await completion“ What does that even mean?

Slide 88

Slide 88 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 // Just take some of those createNodes.take(5); „Cancelled subscription does not await completion“ What does that even mean?

Slide 89

Slide 89 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 // Or more explicit createNodes .as(StepVerifier::create) .expectNext(1, 2, 3, 4, 5) .thenCancel() .verify(); „Cancelled subscription does not await completion“ What does that even mean?

Slide 90

Slide 90 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 // Can we verify it? Flux.using( driver::rxSession, session -> session.run("MATCH (s:SomeNode) RETURN count(s) as cnt").records(), RxSession::close ) .map(r -> r.get("cnt").asLong()) .single().as(StepVerifier::create).expectNext(1000L).verifyComplete(); „Cancelled subscription does not await completion“ What does that even mean?

Slide 91

Slide 91 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Depends

Slide 92

Slide 92 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Cancellation • Happens when the browser goes away • Probably not a good idea to return transactional flows from web endpoints (The same has been said for @Transactional on web methods for a long time!) • Again: .first(), .take(n) • Also limitRequest(n)

Slide 93

Slide 93 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 R2DBC

Slide 94

Slide 94 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Reactive Relational Database Connectivity • A specification designed from the ground up for reactive programming • End to end reactive and non-blocking

Slide 95

Slide 95 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Dependencies • Reactive Streams • Java 8

Slide 96

Slide 96 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 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

Slide 97

Slide 97 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 SPI • ConnectionFactory • Connection • Statement • Result • Row

Slide 98

Slide 98 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Drivers • H2 • Google Cloud Spanner • MySQL • Postgres • SQL Server • SAP Hana

Slide 99

Slide 99 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ConnectionFactory Transactions • Publisher beginTransaction(); • Publisher commitTransaction(); • Publisher rollbackTransaction();

Slide 100

Slide 100 text

Demo #Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 101

Slide 101 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Spring Data R2DBC •R2dbcTransactionManager

Slide 102

Slide 102 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Spring Framework 5.2 • Reactive Transaction Manager SPI • Support for @Transactional • TransactionalOperator

Slide 103

Slide 103 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Transactional • Method signature declares known reactive type • Requires ReactiveTransactionManager • Code path for reactive transaction management • Otherwise • Uses PlatformTransactionManager

Slide 104

Slide 104 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Spring Data R2DBC • Demo @Transactional • Demo TransactionalOperator

Slide 105

Slide 105 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Data escape • Transactional data escapes before transaction completion • Demo

Slide 106

Slide 106 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Neo4j

Slide 107

Slide 107 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 What is Neo4j? • A (property) graph database • An ecosystem • I work on Spring and Spring Data integration as part of the drivers team

Slide 108

Slide 108 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 A Property Graph :Movie :Person :Person Nodes represents objects (Nouns) :DIRECTED :ACTED_IN role: someRole name: someName Relationships connect nodes and represent actions (verbs) Both nodes and relationships can have properties

Slide 109

Slide 109 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 The whiteboard model IS the physical model • Just fill the abstract nodes with content

Slide 110

Slide 110 text

Demo #Devoxx #ReactiveProgramming @mp911de and @rotnroll666

Slide 111

Slide 111 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Neo4j 4.0 • Reactive Cypher engine • Reactive Driver available (Beta) • Spring Data Neo4j RX (Public preview) • Imperative and reactive transaction managers

Slide 112

Slide 112 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Building blocks of Neo4j driver Driver Top level object for all Neo4j interaction Session Logical context for sequence of transactions Transaction Unit of work Statement result Stream of records plus metadata

Slide 113

Slide 113 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Building blocks of Neo4j driver Driver Session Connection pool Connection Connection Server A Server B spawns borrows owns owns to

Slide 114

Slide 114 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Building blocks of Neo4j driver • Session is a logical concept over the connection • One ongoing transaction per session • Thus, the connection is bound to the transaction

Slide 115

Slide 115 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Challenges • Driver shall provide a similar surface for various languages • Java • JavaScript • Python • .NET

Slide 116

Slide 116 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 More challenges • Already two different programming models • Imperative / Blocking • Asynchronous (Pretty much the default in .NET, feels like Co- Routines in Kotlin / Lightweight Threads in Loom) • Supported for all languages • Reactive coming up • Java • JavaScript • .NET

Slide 117

Slide 117 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Imperative Transactions

Slide 118

Slide 118 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Test void implicit() { // Aka "Auto-Commit" try (Session session = driver.session()) { long personId = session .run( "CREATE (a:Person {name: $name}) RETURN id(a) as id“, parameters("name", NAME)) .single().get("id").asLong(); } } Implicit

Slide 119

Slide 119 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Test void txFunctions() { try (Session session = driver.session()) { long personId = session.writeTransaction( tx -> tx.run( "CREATE (a:Person {name: $name}) RETURN id(a) as id“, parameters("name", NAME)) .single().get("id").asLong()); } } Transactional functions

Slide 120

Slide 120 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Test void explicit() { try (Session session = driver.session()) { Transaction tx = session.beginTransaction(TransactionConfig.builder().build()); long personId = tx.run( "CREATE (a:Person {name: $name}) RETURN id(a) as id“, parameters("name", NAME)) .single().get("id").asLong(); tx.commit(); } } Explicit

Slide 121

Slide 121 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Reactive Transactions

Slide 122

Slide 122 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 RxSession session = driver.rxSession(); Publisher txPublisher = session.beginTransaction(); RxTransaction tx; RxStatementResult result = tx.run(); Publisher recordPublisher = result.records() Publisher commit = tx.commit(); Publisher rollback = tx.rollback(); Reactive surface

Slide 123

Slide 123 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Test void implicit() { Flux personCreation = Flux.using( driver::rxSession, session -> session.run( "CREATE (a:Person {name: $name}) RETURN id(a) as id“, parameters("name", NAME) ).records(), RxSession::close ).map(r -> r.get("id").asLong()); StepVerifier.create(personCreation) .expectNextCount(1) .verifyComplete(); } Implicit

Slide 124

Slide 124 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Test void txFunctions() { RxTransactionWork> txFunction = tx -> Flux.from(tx.run( "CREATE (a:Person {name: $name}) RETURN id(a) as id", parameters("name", NAME)).records() ) .map(r -> r.get("id").asLong()); Flux personCreation = Flux.using(driver::rxSession, session -> session.writeTransaction(txFunction), RxSession::close); StepVerifier.create(personCreation) .expectNextCount(1) .verifyComplete(); } Transactional functions

Slide 125

Slide 125 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Test void explicit() { Function> actualWork = session -> Flux.usingWhen(session.beginTransaction(), // Yes, this looks pretty much like the `txFunction` in the example before tx -> tx.run( "CREATE (a:Person {name: $name}) RETURN id(a) as id", parameters("name", NAME) ).records(), RxTransaction::commit, // Success case (tx, e) -> tx.rollback(), // Error / exceptional case RxTransaction::commit // Cancelation ).map(r -> r.get("id").asLong()); Flux personCreation = Flux.using(driver::rxSession, actualWork, RxSession::close); } Explicit

Slide 126

Slide 126 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Spring Data Neo4j⚡RX (SDN/RX)

Slide 127

Slide 127 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 How does SDN/RX differ from previous SDN? • Modular design • Fundamental design differences (e.g. mutability, incremental mapping) • SDN/OGM layers are now combined • Transport functionality moved entirely to Java driver • Supports all "findBy*" methods • Query by Example • Integration with Spring 5.2’s Reactive Transaction Manager

Slide 128

Slide 128 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 SDN/RX Spring Data Repositories Neo4j Template Neo4j Client Driver Neo4j „uses“ sdn-rx-spring-boot-starter neo4j-java-driver-spring-boot-starter provides provides Integration with Spring Transactions from here on SDN/RX components

Slide 129

Slide 129 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jClient reactiveClient; Flux> directorAndMovies = reactiveClient .query( "MATCH (p:Person) - [:DIRECTED] -> (m:Movie {title: $title})," + " (p) - [:WROTE] -> (om:Movie) " + "WHERE p.name =~ $name " + " AND p.born < $someDate.year " + "RETURN p, om" ) .bind(LocalDate.of(1979, 9, 21)).to("someDate") .bindAll(Map.of("title", "The Matrix", "name", "Li.*")) .fetch() .all(); SDN/RX how does it look?

Slide 130

Slide 130 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTemplate reactiveTemplate; Flux movies = reactiveTemplate .findAll(MovieEntity.class); SDN/RX how does it look?

Slide 131

Slide 131 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 public interface MovieRepository extends ReactiveNeo4jRepository { Mono findOneByTitle(String title); } SDN/RX how does it look?

Slide 132

Slide 132 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 @Service public class MovieService { @Transactional public Flux doSomething() { // Return type indicating reactive or imperative return Flux.empty(); } void doSomethingElse() { ReactiveNeo4jTemplate reactiveTemplate; TransactionalOperator transactionalOperator; Flux movies = transactionalOperator.transactional( reactiveTemplate.findAll(MovieEntity.class) ); } } And transactions?

Slide 133

Slide 133 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTransactionManager • Uses explicit reactive transactions • Uses the driver instance as lookup for the transactional resource • Stores both the session and transaction belonging to that session into resource holder

Slide 134

Slide 134 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTransactionManager • Basically this, in a Spring way: Function> actualWork = session -> Flux.usingWhen( session.beginTransaction(), tx -> Flux.just(1L), RxTransaction::commit, (tx, e) -> tx.rollback(), RxTransaction::commit); Flux completeUnitOfWork = Flux.using(driver::rxSession, actualWork, RxSession::close)

Slide 135

Slide 135 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTransactionManager • Basically this, in a Spring way: • Session acquisition Function> actualWork = session -> Flux.usingWhen( session.beginTransaction(), tx -> Flux.just(1L), RxTransaction::commit, (tx, e) -> tx.rollback(), RxTransaction::commit); Flux completeUnitOfWork = Flux.using(driver::rxSession, actualWork, RxSession::close)

Slide 136

Slide 136 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTransactionManager • Basically this, in a Spring way: • Session acquisition • Starting transaction Function> actualWork = session -> Flux.usingWhen( session.beginTransaction(), tx -> Flux.just(1L), RxTransaction::commit, (tx, e) -> tx.rollback(), RxTransaction::commit); Flux completeUnitOfWork = Flux.using(driver::rxSession, actualWork, RxSession::close)

Slide 137

Slide 137 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTransactionManager • Basically this, in a Spring way: • Session acquisition • Starting transaction • Executing stuff Function> actualWork = session -> Flux.usingWhen( session.beginTransaction(), tx -> Flux.just(1L), RxTransaction::commit, (tx, e) -> tx.rollback(), RxTransaction::commit); Flux completeUnitOfWork = Flux.using(driver::rxSession, actualWork, RxSession::close)

Slide 138

Slide 138 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTransactionManager • Basically this, in a Spring way: • Session acquisition • Starting transaction • Executing stuff • Commit or rollback Function> actualWork = session -> Flux.usingWhen( session.beginTransaction(), tx -> Flux.just(1L), RxTransaction::commit, (tx, e) -> tx.rollback(), RxTransaction::commit); Flux completeUnitOfWork = Flux.using(driver::rxSession, actualWork, RxSession::close)

Slide 139

Slide 139 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 ReactiveNeo4jTransactionManager • Basically this, in a Spring way: • Session acquisition • Starting transaction • Executing stuff • Commit or rollback • Closing session Function> actualWork = session -> Flux.usingWhen( session.beginTransaction(), tx -> Flux.just(1L), RxTransaction::commit, (tx, e) -> tx.rollback(), RxTransaction::commit); Flux completeUnitOfWork = Flux.using(driver::rxSession, actualWork, RxSession::close)

Slide 140

Slide 140 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Neo4j resources

Slide 141

Slide 141 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Neo4j • https://neo4j.com/download/ • Neo4j Desktop (Analyst centric) • Neo4j Server (Community and Enterprise Edition) Community Edition: GPLv3 Enterprise Edition: Proprietary

Slide 142

Slide 142 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Neo4j Datasets • Preconfigured instance with several different datasets https://neo4j.com/sandbox-v2/ • Neo4j Graph Gists, Example Models and Cypher Queries https://neo4j.com/graphgists/ • Panama papers and other offshore leaks https://offshoreleaks.icij.org/

Slide 143

Slide 143 text

#Devoxx #ReactiveProgramming @mp911de and @rotnroll666 Spring related • Neo4j Driver Spring Boot Starter https://github.com/neo4j/neo4j-java-driver-spring-boot-starter • Spring Data Neo4j⚡RX https://github.com/neo4j/sdn-rx/