WebFlux Spring Boot @Transactional with reactive MongoDB



WebFlux Spring Boot@Transactional注释与响应式MongoDB一起工作吗?

我使用WebFlux Spring Boot与响应式MongoDB,如:

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'
...

我标记了我的一个方法@Transactional来测试。但是注释似乎对我不起作用。如果在这个方法中发生错误,那么它仍然会向我的mongoDB数据库添加一行。

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;
});
}

我错过了什么或春启动@Transactional注释不工作与反应性MongoDB?

我使用MongoDB v5.0.8

似乎响应式MongoDB的Spring Data需要显式设置一个特殊的beantransactionManager。一旦我将这个bean添加到响应式MongoDB的配置中,@Transactional注释就开始工作了。因此,在我的问题中张贴的示例方法不再向数据库添加新行,如果方法内部发生错误。

下面是我的transactionManagerbean配置:

@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);
}

注:事实证明,transactionManagerbean的定义不足以在响应式MongoDB中启用事务。MongoDB的服务器也应该配置replication。我遵循了这些步骤,它对我很有效。

我为TransactionManager使用了上述配置,但随后我的应用程序出现错误

Command failed with error 13 (Unauthorized): 'command find requires authentication' on server localhost:27017

看起来蒙古客户端需要用户名、数据库名和密码才能正常工作。

@Configuration
@EnableReactiveMongoRepositories
@AllArgsConstructor
public class MongoRepositoryConfiguration extends AbstractReactiveMongoConfiguration {
private final MongoProperties mongoProperties;
@Override
public MongoClient reactiveMongoClient() {
//Create a mongo client with credentials
MongoCredential credential = MongoCredential.createCredential(mongoProperties.getUsername(), mongoProperties.getDatabase(), mongoProperties.getPassword());
return MongoClients.create(
MongoClientSettings.builder()
.credential(credential)
.build()
);
}
@Override
protected String getDatabaseName() {
return mongoProperties.getDatabase();
}

@Bean
ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory) {
return new ReactiveMongoTransactionManager(reactiveMongoDatabaseFactory);
}
}