Skip to content

Commit 988b31b

Browse files
#107 - Polishing.
Extract method references for better readability. Add missing tests and update documentation. Add delay for transactional MySql tests to avoid failures due to potentially delayed transaction id storage within the database. Original Pull Request: #107
1 parent 79e3294 commit 988b31b

17 files changed

+513
-181
lines changed

src/main/asciidoc/reference/r2dbc-transactions.adoc

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,84 @@
44
A common pattern when using relational databases is grouping multiple queries within a unit of work that is guarded by a transaction.
55
Relational databases typically associate a transaction with a single transport connection.
66
Using different connections hence results in utilizing different transactions.
7-
Spring Data R2DBC includes transaction-awareness in `DatabaseClient` that allows you to group multiple statements within the same transaction using https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction[Spring's Transaction Management].
7+
Spring Data R2DBC includes transaction-awareness in `DatabaseClient` that allows you to group multiple statements within
8+
the same transaction using https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction[Spring's Transaction Management].
89
Spring Data R2DBC provides a implementation for `ReactiveTransactionManager` with `ConnectionFactoryTransactionManager`.
910
See <<r2dbc.connections.ConnectionFactoryTransactionManager>> for further details.
1011

1112
.Programmatic Transaction Management
1213
====
1314
[source,java]
1415
----
15-
ConnectionFactoryTransactionManager tm = new ConnectionFactoryTransactionManager(connectionFactory);
16-
TransactionalOperator operator = TransactionalOperator.create(tm);
17-
DatabaseClient db = DatabaseClient.create(connectionFactory);
16+
ReactiveTransactionManager tm = new ConnectionFactoryTransactionManager(connectionFactory);
17+
TransactionalOperator operator = TransactionalOperator.create(tm); <1>
1818
19-
Mono<Void> atomicOperation = db.execute().sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
20-
.bind("id", "joe")
21-
.bind("name", "Joe")
22-
.bind("age", 34)
23-
.fetch().rowsUpdated()
24-
.then(db.execute().sql("INSERT INTO contacts (id, name) VALUES(:id, :name)")
25-
.bind("id", "joe")
26-
.bind("name", "Joe")
27-
.fetch().rowsUpdated())
28-
.then()
29-
.as(operator::transactional);
19+
DatabaseClient client = DatabaseClient.create(connectionFactory);
20+
21+
Mono<Void> atomicOperation = client.execute().sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
22+
.bind("id", "joe")
23+
.bind("name", "Joe")
24+
.bind("age", 34)
25+
.fetch().rowsUpdated()
26+
.then(client.execute().sql("INSERT INTO contacts (id, name) VALUES(:id, :name)")
27+
.bind("id", "joe")
28+
.bind("name", "Joe")
29+
.fetch().rowsUpdated())
30+
.then()
31+
.as(operator::transactional); <2>
3032
});
3133
----
34+
<1> Associate the `TransactionalOperator` with the `ReactiveTransactionManager`.
35+
<2> Bind the operation to the `TransactionalOperator`.
3236
====
3337

34-
https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative[Spring's declarative Transaction Management] is a less invasive, annotation-based approach to transaction demarcation.
38+
https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative[Spring's declarative Transaction Management]
39+
is a less invasive, annotation-based approach to transaction demarcation.
3540

3641
.Declarative Transaction Management
3742
====
3843
[source,java]
3944
----
40-
class MyService {
45+
@Configuration
46+
@EnableTransactionManagement <1>
47+
class Config extends AbstractR2dbcConfiguration {
4148
42-
private final DatabaseClient db;
49+
@Override
50+
public ConnectionFactory connectionFactory() {
51+
return // ...
52+
}
4353
44-
MyService(DatabaseClient db) {
45-
this.db = db;
54+
@Bean
55+
ReactiveTransactionManager txMgr(ConnectionFactory connectionFactory) { <2>
56+
return new ConnectionFactoryTransactionManager(connectionFactory);
4657
}
58+
}
4759
60+
@Service
61+
class MyService {
62+
63+
private final DatabaseClient client;
64+
65+
MyService(DatabaseClient client) {
66+
this.client = client;
67+
}
4868
4969
@Transactional
5070
public Mono<Void> insertPerson() {
5171
52-
return db.execute().sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
72+
return client.execute().sql("INSERT INTO person (id, name, age) VALUES(:id, :name, :age)")
5373
.bind("id", "joe")
5474
.bind("name", "Joe")
5575
.bind("age", 34)
5676
.fetch().rowsUpdated()
57-
.then(db.execute().sql("INSERT INTO contacts (id, name) VALUES(:id, :name)")
58-
.bind("id", "joe")
59-
.bind("name", "Joe")
60-
.fetch().rowsUpdated())
61-
.then();
77+
.then(client.execute().sql("INSERT INTO contacts (id, name) VALUES(:id, :name)")
78+
.bind("id", "joe")
79+
.bind("name", "Joe")
80+
.fetch().rowsUpdated())
81+
.then();
6282
}
6383
}
6484
----
85+
<1> Enable declarative transaction management.
86+
<2> Provide a `ReactiveTransactionManager` implementation to back reactive tansaction features.
6587
====

src/main/java/org/springframework/data/r2dbc/function/connectionfactory/ConnectionFactoryTransactionManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,

0 commit comments

Comments
 (0)