[Spring] Scheduler를 이용하여 정해진 시간에 멤버쉽 업데이트

오형상·2024년 1월 18일
0

Spring

목록 보기
9/9
post-thumbnail

적용방법

1. @EnableScheduling 어노테이션을 붙여준다.

@EnableScheduling

  • @Scheduled 어노테이션을 감지하고 만들어 준 스케줄러를 동작할 수 있게 해주는 어노테이션입니다.
  • Spring은 고유한 TaskScheduler 인터페이스 타입의 빈이나 taskScheduler 라는 이름을 가진 빈을 찾습니다. 만약 존재하지 않는다면 자동 설정에 의해 local single thread 스케줄러가 생성되어 사용됩니다.
@EnableScheduling // background task executer가 생성된다.
@SpringBootApplication
public class OnlineshopApplication {

    public static void main(String[] args) {
        SpringApplication.run(OnlineshopApplication.class, args);
    }

}

2. 스케줄러 메서드를 만들어줍니다.

@Scheduled

  • 스케줄러 메서드를 표시하기 위한 어노테이션입니다.
  • 이 메서드는 인수를 가질 수 없습니다.
  • 일반적으로 void return 형태로 사용하여 그렇지 않다면 return 값이 무시될 수 있습니다.

cron : cron 표현식을 지원. ‘초 분 시 일 월 주 (년)’ 으로 표현
fixedDelay : ms 단위. 이전 작업이 끝난 시점부터 고정된 호출 간격을 설정.
fixedRate : ms 단위. 이전 작업이 수행되기 시작한 시점부터 고정된 호출 간격 설정.
initialDelay : 초기 지연 시간.(스케줄러에서 메서드가 등록되자마자 수행하지 않고 설정해준 시간 후부터 동작)
zone : cron 표현식을 사용할 때 적용할 time zone. 따로 지정하지 않으면 서버의 time zone

    /**
     * 주기적으로 모든 고객의 멤버십을 업데이트하는 메서드.
     * 월요일 새벽 4시에 실행됩니다.
     */
    @Transactional
    @Scheduled(cron = "0 0 4 ? * MON")
    public void updateAllMemberShip() {
        // 모든 고객 정보를 조회합니다.
        List<Customer> customers = customerRepository.findAll();

        // 각 고객에 대해 멤버십을 업데이트합니다.
        for (Customer customer : customers) {
            updateMembershipForCustomer(customer);
        }
    }

    /**
     * 특정 고객의 멤버십을 업데이트하는 메서드.
     *
     * @param customer 업데이트할 고객
     */
    private void updateMembershipForCustomer(Customer customer) {
        // 고객의 총 구매액을 조회합니다.
        BigDecimal totalPurchaseAmount = customer.getTotalPurchaseAmount();

        // 현재 총 구매액에 따라 업그레이드 가능한 멤버십을 조회합니다.
        memberShipRepository.findNextMemberShip(totalPurchaseAmount)
                .stream()
                .findFirst()
                .filter(memberShip -> totalPurchaseAmount.compareTo(memberShip.getBaseline()) > 0)
                .ifPresent(memberShip -> {
                    // 멤버십 업데이트를 로그에 기록합니다.
                    log.info("{} 회원이 {}로 업데이트 되었습니다.", customer.getId(), memberShip.getLevel());
                    // 실제 멤버십을 업데이트합니다.
                    customer.upgradeMemberShip(memberShip);
                });
    }

0개의 댓글