I am using spring-boot 2.4.2 with webflux to connect to a postgres database.
I observed a behavior while using @Transactional
that I don't understand.
To showcase the behavior, I created an example application that attempts to add rows to two tables; table "a" and table "b". The insert to table "a" is expected to fail with a duplicate key violation. Given that transactional is used, I expect no rows to be added to table "b".
However, depending which method I annotate with @Transactional
I get different results.
If I annotate the controller method, things work as expected and no row is added to table B.
@PostMapping("/")
@Transactional
public Mono<Void> postEntities() {
return demoService.doSomething();
}
DemoService looks like this:
public Mono<Void> doSomething() {
return internal();
}
public Mono<Void> internal() {
Mono<EntityA> clash = Mono.just(EntityA.builder().name("clash").build()).flatMap(repositoryA::save);
Mono<EntityB> ok = Mono.just(EntityB.builder().name("ok").build()).flatMap(repositoryB::save);
return ok.and(clash);
}
If I move the @Transactional
annotation from the controller to doSomething()
, then the transactions still work as expected.
However, if I move the @Transactional
annotation to internal()
, then transactions don't work as expected. A row is added to table "b".
The full code of this example is here: https://github.com/alampada/pg-spring-r2dbc-transactional
I don't understand why moving the annotation to the internal()
method causes issues to transaction handling. Could you please explain?