Should not modify anything when use readonly transaction.
ver: spring-boot-2.7.2 with spring-r2dbc-5.3.22
data class Sample(
@Id val id: Int,
val name: String
)
// SampleService.kt
val entityTemplate: R2dbcEntityTemplate
@Transactional(readOnly = true)
fun insertWithReadOnlyTransaction(sample: Sample): Mono<Sample> {
return entityTemplate.insert(sample)
}
// unit test should failed
@Test
fun `should failed by readonly transaction`() {
sampleService.insertWithReadOnlyTransaction()
.test()
.expectError()
.verify()
}
2022-08-16 13:05:26.336 DEBUG 10668 --- [ main] o.s.r2dbc.core.DefaultDatabaseClient : Executing SQL statement [DELETE FROM sample WHERE sample.id = $1]
2022-08-16 13:05:26.419 DEBUG 10668 --- [ main] o.s.r.c.R2dbcTransactionManager : Creating new transaction with name [tech.simter.r2dbc.kotlin.repository.SampleService.insertWithReadOnlyTransaction]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2022-08-16 13:05:26.434 DEBUG 10668 --- [ main] o.s.r.c.R2dbcTransactionManager : Acquired Connection [MonoRetry] for R2DBC transaction
2022-08-16 13:05:26.437 DEBUG 10668 --- [ main] o.s.r.c.R2dbcTransactionManager : Switching R2DBC Connection [PooledConnection[io.r2dbc.h2.H2Connection@1958c0d9]] to manual commit
2022-08-16 13:05:26.496 DEBUG 10668 --- [ main] o.s.r2dbc.core.DefaultDatabaseClient : Executing SQL statement [INSERT INTO sample (id, name) VALUES ($1, $2)]
2022-08-16 13:05:26.521 DEBUG 10668 --- [ main] o.s.r.c.R2dbcTransactionManager : Initiating transaction commit
2022-08-16 13:05:26.522 DEBUG 10668 --- [ main] o.s.r.c.R2dbcTransactionManager : Committing R2DBC transaction on Connection [PooledConnection[io.r2dbc.h2.H2Connection@1958c0d9]]
2022-08-16 13:05:26.531 DEBUG 10668 --- [ main] o.s.r.c.R2dbcTransactionManager : Releasing R2DBC Connection [PooledConnection[io.r2dbc.h2.H2Connection@1958c0d9]] after transaction
Readonly transaction also can do the insert successfully.
Comment From: snicoll
The Javadoc for readOnly()
states the following:
This just serves as a hint for the actual transaction subsystem; it will not necessarily cause failure of write access attempts. A transaction manager which cannot interpret the read-only hint will not throw an exception when asked for a read-only transaction but rather silently ignore the hint.