Skip to content

Commit

Permalink
사전예약 로직 수정 (#135)
Browse files Browse the repository at this point in the history
* fix(#128): 불필요한 조회 제거, 사전예약 캐시 데이터에 Product 아이디 추가

* feat(#128): 사전예약정보 변경시 캐싱 되어있는 정보 삭제, 오픈되어있는 사전예약정보만 저장할 수 있도록 진행
  • Loading branch information
yooyouny authored Oct 17, 2024
1 parent 57d4311 commit bc4683d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.sparta.product.application.preorder;

import com.sparta.product.domain.model.PreOrder;
import com.sparta.product.domain.model.PreOrderState;
import com.sparta.product.infrastructure.utils.PreOrderRedisDto;
import com.sparta.product.presentation.exception.ProductErrorCode;
import com.sparta.product.presentation.exception.ProductServerException;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
Expand All @@ -14,6 +17,12 @@ public class PreOrderCacheService {
@Cacheable(cacheNames = "preOrder", key = "#preOrderId")
public PreOrderRedisDto getPreOrderCache(Long preOrderId) {
PreOrder preOrder = preOrderService.findPreOrderByPreOrderId(preOrderId);
validatePreOrder(preOrder);
return new PreOrderRedisDto(preOrder);
}

private void validatePreOrder(PreOrder preOrder) {
if (preOrder.getState() != PreOrderState.OPEN_FOR_ORDER)
throw new ProductServerException(ProductErrorCode.NOT_OPEN_FOR_PREORDER);
}
}
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
package com.sparta.product.application.preorder;

import com.sparta.common.domain.entity.KafkaTopicConstant;
import com.sparta.product.domain.model.PreOrder;
import com.sparta.product.domain.model.PreOrderState;
import com.sparta.product.infrastructure.messaging.PreOrderProducer;
import com.sparta.product.presentation.exception.ProductErrorCode;
import com.sparta.product.presentation.exception.ProductServerException;
import com.sparta.product.infrastructure.utils.PreOrderRedisDto;
import dto.OrderCreateRequest;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class PreOrderFacadeService {
private final PreOrderService preOrderService;
private final PreOrderProducer preOrderProducer;
private final PreOrderLockService preOrderLockService;

@Transactional
public void preOrder(Long preOrderId, Long addressId, Long userId) {
PreOrder preOrder = preOrderService.findPreOrderByPreOrderId(preOrderId);
preOrderLockService.reservation(preOrderId, userId);
OrderCreateRequest createRequest =
PreOrderMapper.toDto(preOrder.getProductId().toString(), addressId);
PreOrderRedisDto cachedData = preOrderLockService.reservation(preOrderId, userId);
OrderCreateRequest createRequest = PreOrderMapper.toDto(cachedData.productId(), addressId);
preOrderProducer.send(
KafkaTopicConstant.PROCESS_PREORDER, Long.toString(userId), createRequest);
}

private void validatePreOrder(PreOrder preOrder) {
if (preOrder.getState() != PreOrderState.OPEN_FOR_ORDER)
throw new ProductServerException(ProductErrorCode.NOT_OPEN_FOR_PREORDER);

LocalDateTime now = LocalDateTime.now();
if (now.isBefore(preOrder.getStartDateTime()) || now.isAfter(preOrder.getEndDateTime())) {
throw new ProductServerException(ProductErrorCode.CLOSED_PREORDER);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.sparta.product.infrastructure.utils.PreOrderRedisDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
Expand All @@ -13,8 +14,9 @@ public class PreOrderLockService {
private final PreOrderCacheService cacheService;
private final DistributedLockComponent lockComponent;

public void reservation(long preOrderId, long userId) {
PreOrderRedisDto cachedPreOrder = cacheService.getPreOrderCache(preOrderId);
@Transactional
public PreOrderRedisDto reservation(long preOrderId, long userId) {
PreOrderRedisDto cachedPreOrder = cacheService.getPreOrderCache(preOrderId); // 오픈된 사전예약인지 검증
cachedPreOrder.validateReservationDate(); // 사전예약기간인지 검증
lockComponent.execute( // 락을 걸고
"preOrderLock_%s".formatted(preOrderId),
Expand All @@ -24,5 +26,6 @@ public void reservation(long preOrderId, long userId) {
redisService.validateQuantity(cachedPreOrder, userId); // 이미 예약에 성공한 유저인지, 수량안에 든 유저인지 검증
});
redisService.preOrder(getRedisKeyOfPreOrder(preOrderId), userId);
return cachedPreOrder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
Expand All @@ -36,6 +37,7 @@ public Long createPreOrder(PreOrderCreateRequest request) {
return savedPreOrder.getPreOrderId();
}

@CacheEvict(cacheNames = "preOrder", key = "#request.preOrderId()")
public PreOrderResponse updatePreOrder(PreOrderUpdateRequest request) {
PreOrder preOrder = findPreOrderByPreOrderId(request.preOrderId());
if (preOrder.getProductId() != request.productId()) {
Expand Down Expand Up @@ -63,18 +65,21 @@ public Page<PreOrderResponse> getPreOrderList(int page, int size) {
return preOrderRepository.findAllByIsPublicTrue(pageable).map(PreOrderResponse::of);
}

@CacheEvict(cacheNames = "preOrder", key = "#preOrderId")
public PreOrderResponse updateState(Long preOrderId, PreOrderState state) {
PreOrder preOrder = findPreOrderByPreOrderId(preOrderId);
if (state == PreOrderState.OPEN_FOR_ORDER) preOrder.open();
else if (state == PreOrderState.CANCELLED) preOrder.cancel(); // TODO :: 해당 주문건들 sate 전파필요
return PreOrderResponse.of(preOrder);
}

@CacheEvict(cacheNames = "preOrder", key = "#preOrderId")
public void deletePreOrder(Long preOrderId) {
PreOrder preOrder = findPreOrderByPreOrderId(preOrderId);
preOrderRepository.delete(preOrder);
}

@Transactional(readOnly = true)
public PreOrder findPreOrderByPreOrderId(Long preOrderId) {
return preOrderRepository
.findByPreOrderIdAndIsPublicTrue(preOrderId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
import com.sparta.product.presentation.exception.ProductErrorCode;
import com.sparta.product.presentation.exception.ProductServerException;
import java.time.LocalDateTime;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public record PreOrderRedisDto(
Long preOrderId,
String productId,
Integer availableQuantity,
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
Expand All @@ -21,6 +24,7 @@ public record PreOrderRedisDto(
public PreOrderRedisDto(PreOrder preOrder) {
this(
preOrder.getPreOrderId(),
preOrder.getProductId().toString(),
preOrder.getAvailableQuantity(),
preOrder.getStartDateTime(),
preOrder.getEndDateTime());
Expand Down

0 comments on commit bc4683d

Please sign in to comment.