JAVA/프로젝트

스프링부트 스케줄링 적용 @EnableScheduling

whyHbr 2024. 7. 16. 16:49
728x90
반응형

리뷰가 생성 될 때 마다 즉각적으로 평점 갱신했던 것을 스케줄링을 통해 매일 자정에 하는 것으로 변경

 

변경 전 :

@Transactional
public ReviewResponse createReview(Long memberId, Long accommodationId,
    ReviewRequest reviewRequest) {
    Accommodation accommodation = findAccommodation(accommodationId);
    Member member = findMember(memberId);
    Reservation reservation = findReservation(reviewRequest.getReservationId());
    Long productId = reservation.getProduct().getId();
    productRepository.findByIdAndAccommodationId(productId, accommodationId)
        .orElseThrow(() -> new ProductException(ErrorType.NOT_FOUND));
    //중복 리뷰 검증
    if (reviewRepository.existsByReservationId(reservation.getId())) {
        throw new ReviewException(ErrorType.DUPLICATED_REVIEW);
    }
    //체크아웃 시간, 작성 시간 검증
    LocalDate checkOutTime = reservation.getCheckOutDate();
    LocalDate createdAt = LocalDate.now();
    validInputs(checkOutTime, createdAt);

    accommodation.updateGrade(reviewRequest.getGrade());

    Review review = Review.from(reviewRequest, accommodation, member, reservation);
    reviewRepository.save(review);
    return ReviewResponse.from(review);
}

 

 

변경 후:

@Transactional
public ReviewResponse createReview(Long memberId, Long accommodationId,
    ReviewRequest reviewRequest) {
    Accommodation accommodation = findAccommodation(accommodationId);
    Member member = findMember(memberId);
    Reservation reservation = findReservation(reviewRequest.getReservationId());
    Long productId = reservation.getProduct().getId();
    productRepository.findByIdAndAccommodationId(productId, accommodationId)
        .orElseThrow(() -> new ProductException(ErrorType.NOT_FOUND));
    //중복 리뷰 검증
    if (reviewRepository.existsByReservationId(reservation.getId())) {
        throw new ReviewException(ErrorType.DUPLICATED_REVIEW);
    }
    //체크아웃 시간, 작성 시간 검증
    LocalDate checkOutTime = reservation.getCheckOutDate();
    LocalDate createdAt = LocalDate.now();
    validInputs(checkOutTime, createdAt);

    Review review = Review.from(reviewRequest, accommodation, member, reservation);
    reviewRepository.save(review);
    return ReviewResponse.from(review);
}
private BigDecimal calculateGrade(List<Review> reviews, Accommodation accommodation) {
    if (reviews.isEmpty()) {
        return accommodation.getGrade(); //return BigDecimal.ZERO;
    }
    BigDecimal totalGrade = reviews.stream()
        .map(Review::getGrade)
        .reduce(BigDecimal.ZERO, BigDecimal::add);

    return totalGrade.divide(BigDecimal.valueOf(reviews.size()), 1, RoundingMode.HALF_UP);
}

 

추가된 클래스 :

@Component
@RequiredArgsConstructor
@Slf4j
//@EnableAsync 병렬적 사용
public class ReviewScheduler {

    private final ReviewService reviewService;

    // 매일 자정 실행
    //@Async 비동기
    @Scheduled(cron = "0 0 0 * * ?")
    public void updateGrade() {
        try {
            reviewService.updateGrade();
            log.info("현재 시간 : {}", LocalDateTime.now());
        }catch (Exception e ) {
            log.error("Error updating grades: {}", e.getMessage(), e);
        }
    }
}

 

그리고 메인  Application 에 추가

@EnableScheduling

 

지정한 시간이 되면 변경 되는 것을 볼 수 있다.

728x90