У меня есть сценарий, в котором я вызываю метод внутри Mono-последовательности, в зависимости от способа вызова последовательности, я либо получаю ошибку, либо последовательность успешна.
Успешная последовательность:
@Override
public Mono<User> getUserDetails(String userId) {
return reactiveValueOps
.get(userId)
.switchIfEmpty(userService.getUser(Long.valueOf(userId))
.flatMap(this::setUserDetails));
}
@Override
public Mono<User> setUserDetails(User user) {
return reactiveValueOps
.set(String.valueOf(user.getId()), user, Duration.ofDays(SESSION_PERSISTENCE_DURATION))
.flatMap(b -> Mono.just(user));
}
Последовательность ошибок:
@Override
public Mono<User> getUserDetails(String userId) {
return reactiveValueOps
.get(userId)
.switchIfEmpty(Mono.defer(() -> {
Mono<User> user = userService.getUser(Long.valueOf(userId));
Mono<Boolean> valueSet = setUserDetails(user);
return valueSet.zipWith(user, (v, u) -> u);
}));
}
@Override
public Mono<Boolean> setUserDetails(Mono<User> user) {
return user.switchIfEmpty(Mono.defer(() ->
Mono.error(new UnsupportedOperationException("Cannot persist empty User Object"))))
.flatMap(u -> reactiveValueOps.set(String.valueOf(u.getId()), u, Duration.ofDays(1L)));
}
userService.getUser
метод либо возвращает пользователя из БД, либо создает нового пользователя, получающего данные от третьей стороныAPI, во 2-й последовательности я получаю эту ошибку:
ERROR: duplicate key value violates unique constraint
Эта ошибка возникает, только если пользователь еще не присутствует в БД, нет проблем, если он находится в базе данных и только для второго потока выполнения.Что-то не так происходит, когда я использую zipWith
?