Войти Регистрация
Код-ревью

13. Резерв товара на складе при оформлении

Средняя

Java · 41 строк

При оформлении заказа товары корзины резервируются на 15 минут. Если заказ не оплачен, планировщик возвращает остаток на склад. findByOrderId в Spring Data возвращает List<Reservation>.

В распродажу — 3 000 оформлений в секунду и около 2 млн живых резервов. Отметьте строки с ошибками.

В работе: Оформление заказа: от резерва зависит, не продадим ли мы товар, которого нет на полке.

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
транзакциигонкиSpring Dataпроизводительность

Источник: на задачах Ozon: склады и резервы. Условие пересказано своими словами.

Давали на собеседовании? Ответов пока мало — ваш поможет.
  1. @Service
  2. public class ReservationService {
  3. private final StockRepository stocks;
  4. private final ReservationRepository reservations;
  5. public ReservationService(StockRepository stocks, ReservationRepository reservations) {
  6. this.stocks = stocks;
  7. this.reservations = reservations;
  8. }
  9. @Transactional
  10. public ReservationResult reserve(String orderId, List<CartItem> items) {
  11. for (CartItem item : items) {
  12. Stock stock = stocks.findBySku(item.getSku());
  13. if (stock.getAvailable() < item.getQuantity()) {
  14. return ReservationResult.failed(item.getSku());
  15. }
  16. stock.setAvailable(stock.getAvailable() - item.getQuantity());
  17. stocks.save(stock);
  18. reservations.save(new Reservation(orderId, item.getSku(), item.getQuantity(),
  19. LocalDateTime.now().plusMinutes(15)));
  20. }
  21. return ReservationResult.ok();
  22. }
  23. @Scheduled(fixedDelay = 60_000)
  24. public void releaseExpired() {
  25. for (Reservation r : reservations.findAll()) {
  26. if (r.getExpiresAt().isBefore(LocalDateTime.now())) {
  27. Stock stock = stocks.findBySku(r.getSku());
  28. stock.setAvailable(stock.getAvailable() + r.getQuantity());
  29. stocks.save(stock);
  30. reservations.delete(r);
  31. }
  32. }
  33. }
  34. public boolean isReserved(String orderId) {
  35. return reservations.findByOrderId(orderId) != null;
  36. }
  37. }