I'm currently learning about Project Reactor using Spring-WebFlux.
I have created a simple service that will insert into two collections in a sequence. Firstly, my service will insert into the list collection, and after that it will insert into the details collection. If, both operations succeed, it will return an instance of the first operation (Insert into list collection), if one of them doesn't succeed, it will rollback any changes created by the operation before it.
Here is my snippet:
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()
}
I feel like this is kind of a dirty way to create a Mono. Since the second operation is a block operation. Of course, I could just do a insert list then insert details then get list. But, this will actually be calling the DB for 3 times, instead of 2 times like my code above.
Is there any way for me to create a non-blocking operation and only calling the DB 2 times?
Thank you.
I'm not familiar with Kotlin, but with Java you could do it like:
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 ANSWER, thanks David:
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))
}
}