javamongodbspring-bootreactivespring-data-r2dbc

WebFlux Spring Boot @Transactional with reactive MongoDB


Does WebFlux Spring Boot @Transactional annotation work with reactive MongoDB?

I use WebFlux Spring Boot with reactive MongoDB like:

    id 'org.springframework.boot' version '2.6.7'
    ...
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive'
    ...

I marked one of my method @Transactional to test. But it seems the annotation does not work for me. If an error occurs inside this method, then it still adds a row to my mongoDB database.

      import org.springframework.transaction.annotation.Transactional;

      ...

      @Transactional
      public Mono<Chat> createChat(Chat chat) {
        return chatRepository
            .save(chat)
            .map(
                c-> {
                  if (true) {
                    throw new RuntimeException();
                  }
                  return c;
                });
      }

Do I miss something or Spring Boot @Transactional annotation does not work with reactive MongoDB?

I use MongoDB v5.0.8


Solution

  • It seems like that Spring Data for reactive MongoDB requires to set explicitly a special bean transactionManager. As soon as I have added this bean to my configuration for the reactive MongoDB, the @Transactional annotation started working. So the example method posted in my question does not add a new row to the database anymore if an error occurs inside the method.

    Here is my configuration with transactionManager bean:

    @Configuration
    @EnableReactiveMongoRepositories
    @AllArgsConstructor
    public class ReactiveMongoConfiguration extends AbstractReactiveMongoConfiguration {
    
      private final MongoProperties mongoProperties;
    
      @Override
      public MongoClient reactiveMongoClient() {
        return MongoClients.create();
      }
    
      @Override
      protected String getDatabaseName() {
        return mongoProperties.getDatabase();
      }
    
      @Bean
      ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory) {
        return new ReactiveMongoTransactionManager(reactiveMongoDatabaseFactory);
      }
    

    P.S. It turns out the defining of transactionManager bean is not enough to enable transactions in reactive MongoDB. The very server of MongoDB should be also configured with replication. I followed these steps and it worked for me.