Код компилируется, тесты зелёные, в проде всё ломается 👇
📦 Задание — code review
Сервис обрабатывает заявки на вывод средств. Требования простые: нельзя выводить больше, чем есть на балансе, и нельзя создавать две заявки одновременно.
@Service
@RequiredArgsConstructor
public class WithdrawalService {
private final AccountRepository accountRepository;
private final WithdrawalRepository withdrawalRepository;
public void requestWithdrawal(Long userId, BigDecimal amount) {
Account account = accountRepository.findByUserId(userId)
.orElseThrow();
if (account.getBalance().compareTo(amount) < 0) {
throw new InsufficientFundsException();
}
boolean hasPending = withdrawalRepository
.existsByUserIdAndStatus(userId, Status.PENDING);
if (hasPending) {
throw new WithdrawalAlreadyPendingException();
}
account.setBalance(account.getBalance().subtract(amount));
accountRepository.save(account);
withdrawalRepository.save(
new Withdrawal(userId, amount, Status.PENDING)
);
}
}
🔹 Задачи
Два запроса от одного пользователя прилетели одновременно. В итоге — баланс ушёл в минус и создались две заявки.
▪️ Объясни
— Точную последовательность событий при конкурентных запросах.
— Спасёт @Transactional над методом или нет? Почему?
— Как исправить это корректно.
Ставьте → 🔥, если нравится формат. Если нет → 🌚
💬 Решения под спойлер. Сравним, какое будет лучше.
🐸 Библиотека собеса по Java
#practise