r2dbc: Spring Data R2DBC CRUD, DatabaseClient, reactive transactions and Testcontainers Postgres (post 2)

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b4VQVEJWetTT1dYzyJ
This commit is contained in:
2026-10-29 04:16:34 +00:00
co-authored by Claude Sonnet 5.5
parent 89358e7b7c
commit 7d7d4e872e
27 changed files with 813 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
tables created by schema.sql: [account, customer, purchase_order]
+6
View File
@@ -0,0 +1,6 @@
save -> id=1 name=Asha Rao
findById -> Customer[id=1, name=Asha Rao, [email protected], tier=GOLD]
update -> name=Asha Rao-Iyer (same id=1, SQL UPDATE)
count -> 1
deleteById-> count now 0
findById(9999) -> empty Mono (completes with no value, no exception)
+2
View File
@@ -0,0 +1,2 @@
built save(...) pipeline, never subscribed -> rows in table: 0
after .block() on the same pipeline -> rows in table: 1
+5
View File
@@ -0,0 +1,5 @@
findByTier(GOLD) -> [Asha Rao, Meera Joshi]
@Query searchByName(%RAO%) -> [Asha Rao]
@Modifying changeTier -> 1 row updated
GOLD customers now -> 3
DatabaseClient totalSpent(ravi) -> 200.00
+6
View File
@@ -0,0 +1,6 @@
findAll() on Customer returns rows only. There is no orders field to be lazy or eager:
Customer[id=1, name=A, [email protected], tier=STANDARD]
1+N queries (4 SQL statements for 3 customers) -> [A:2, B:1, C:0]
two queries (2 SQL statements) -> [A:2, B:1, C:0]
one LEFT JOIN, grouped by hand (1 statement) -> [A:2, B:1, C:0]
all three strategies return identical aggregates: true
+6
View File
@@ -0,0 +1,6 @@
NO transaction, failure after debit -> alice=60.00 bob=50.00 (money vanished)
@Transactional, failure after debit -> alice=100.00 bob=50.00 (rolled back)
TransactionalOperator, failure -> alice=100.00 bob=50.00 (rolled back)
TransactionalOperator, success -> alice=60.00 bob=90.00 (committed)
@Transactional, CHECK(balance>=0) violated on debit -> DataIntegrityViolationException; alice=100.00 bob=50.00
transfer to a non-existent account -> no error at all; alice=90.00 (debited, credit hit 0 rows)
@@ -0,0 +1,5 @@
INDICATIVE, shared 2-vCPU sandbox, database in a container on the same host.
4000 x 'SELECT ... WHERE id = ?' per round, 100 in flight, pool size 20, 5 rounds after 1 warm-up each.
queries/second, sorted:
R2DBC DatabaseClient : [233, 288, 361, 427, 435] median=361
JDBC + virtual threads : [1240, 1281, 1348, 1558, 3084] median=1348
@@ -0,0 +1,4 @@
mvn test with testcontainers-r2dbc removed from the pom:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 57.47 s <<< FAILURE! -- in com.ankurm.r2dbc.R2dbcDemoTest
Failed to instantiate [io.r2dbc.pool.ConnectionPool]: Factory method 'connectionFactory' threw exception with message: org/testcontainers/r2dbc/R2DBCDatabaseContainer
Caused by: java.lang.ClassNotFoundException: org.testcontainers.r2dbc.R2DBCDatabaseContainer