#spring-boot #kotlin #spring-data-mongodb #spring-webflux
#весенняя загрузка #kotlin #spring-данные-mongodb #spring-webflux
Вопрос:
В настоящее время я изучаю Project Reactor с использованием Spring-WebFlux.
Я создал простой сервис, который будет последовательно вставлять в две коллекции. Во-первых, мой сервис будет вставлен в коллекцию list, а после этого он будет вставлен в коллекцию details. Если обе операции завершатся успешно, будет возвращен экземпляр первой операции (Вставить в коллекцию списков), если одна из них не завершится успешно, будет выполнен откат всех изменений, созданных предшествующей операцией.
Вот мой фрагмент:
override fun insert(business: Business): Mono<Business> = businessRepository.save(business)
.doOnSuccess { businezz ->
val businessDetails = businezz.businessDetails
businessDetails!!.idBusiness = businezz.id
businessDetailsService.insert(businessDetails).doOnError {
businessRepository.delete(businezz).subscribe()
}.subscribe()
}
Я чувствую, что это своего рода грязный способ создания Mono. Поскольку вторая операция является блочной операцией. Конечно, я мог бы просто вставить список, затем вставить детали, а затем получить список. Но на самом деле это будет вызывать базу данных 3 раза, а не 2 раза, как в моем коде выше.
Есть ли у меня какой-нибудь способ создать неблокирующую операцию и вызвать базу данных только 2 раза?
Спасибо.
Комментарии:
1. Привет, Дэвид, я удалил тег Java, поскольку в вашем вопросе используется только Kotlin.
2. Спасибо @LppEdd, я подумал, что, поскольку Kotlin — это просто расширение Java, будет нормально добавить тег java. В следующий раз я буду осторожен.
Ответ №1:
Я не знаком с Kotlin, но с Java вы могли бы сделать это следующим образом:
Mono<Business> insert(Business business) {
return businessRepository.save(business)
.flatMap(businezz -> {
BusinessDetails businessDetails = ...;
return businessDetailsService.insert(businessDetails)
.onErrorResume(throwable -> businessRepository
.delete(businezz)
.then(Mono.empty()))
.then(Mono.just(businezz));
});
}
ОТВЕТ KOTLIN, спасибо, Дэвид:
override fun insert(business: Business): Mono<Business> {
return businessRepository.save(business).flatMap { businezz ->
val businessDetails = businezz.businessDetails
businessDetailsService.insert(businessDetails!!).onErrorResume {
businessRepository.delete(businezz).then(Mono.empty())
}.then(Mono.just(businezz))
}
}
Комментарии:
1. Спасибо @Alexander Pankin. Вы подаете мне идею. Последний вопрос, зачем использовать flatMap вместо map? Поскольку я использую Mono, а не Flux
2. В реакторе
flatMap
поток не «выравнивается» до Mono. Мы используем это с Mono или Flux, когда необходимо передать значение «next» другому асинхронному издателю. И мы используемmap
, когда передаем «следующее» значение синхронной функции.3. Спасибо за объяснение!!