Closed anaconda875 closed 5 months ago
This is correct and as designed behavior. Let's take a closer look at what happens here:
personRepository.updateAc().then(Mono.error(new RuntimeException("ttttttttt")))
Without an outer @Transactional
on the controller method, a transaction starts when a subscriber subscribes to personRepository.updateAc()
. The transaction runs until the resulting Mono
emits a completion signal. After completion (and therefore after the transaction is committed) Mono.error(…)
is being executed. The error signal is emitted outside of the transaction and so it does not affect transactional cleanup.
When you in contrast annotate your controller methods with @Transactional
, then the controller method body already is part of the transaction.
One additional note: A Mono
behaves pretty similar to CompletableFuture
. Emission of a data signal already completes the Mono
without a need to emit an additional completion signal. That is the reason why flatMap(i -> Mono.error(…)))
is running after transaction completion.
Let me know whether that makes sense to you.
If annotating @Transactional
on Repository itself cannot do rollback, what is the purpose of putting it on SimpleR2dbcRepository
?
We apply a read-only optimization via @Transactional(readOnly = true)
to allow transaction managers and drivers participate in read-only transactions to reduce overhead.
Also, there are several methods that run multiple SQL statements such as deleteById(Publisher<ID> idPublisher)
that we want to keep within the same transaction.
I'm closing the ticket since the original question has been answered.
I tried to add debug-breakpoints to TransactionInterceptor
and found that those code was not executed even I had called save
or deleteById(Publisher<ID> idPublisher)
. Did I miss something?
Given
In controller methods, I throw
RuntimeException
viaMono.error()
. Expected:personRepository.save()
operation (sinceSimpleR2dbcRepository.save()
is annotated by@Transactional
)personRepository.updateAc()
operation (since it is annotated by@Transactional
, too)Actual: No rollback is done (I verified carefully) Bonus:
@Transactional
to controller methods, rollbacks are performed.r2dbc-postgresql
,spring-boot-starter-webflux
,spring-boot-starter-data-r2dbc
,spring-boot-starter-actuator
), still observed the same behaviors.Is it a bug or a limitation of Spring r2dbc/reactor?