Spring Batch Trouble Shoot2

꽃봉우리·2024년 8월 12일

Trouble Shoot - 휴면계정 활성화 오류

public void activateUser(EmailCheckRequestDto requestDto) {
        User user = userRepository.findByLoginIdAndEmailAndStatus(requestDto.getLoginId(),
            requestDto.getEmail(), UserStatusEnum.INACTIVE_USER).orElseThrow(()
                -> new NotFoundException(USER_NOT_FOUND));

        mailSendService.CheckAuthNum(requestDto.getLoginId(),requestDto);
        verifyEmail(requestDto.getLoginId(), requestDto.getEmail());

        user.fromInactiveToActive();
        userRepository.save(user);
        redisUtil.deleteData(requestDto.getLoginId());
    }

해당 로직에서 save하기 전 user의 상태에는 휴면유저가 아닌 활성화 유저로 값이 들어오는 것을 확인했지만, DB는 바뀌지 않는 오류가 계속 생겼다.

디버그를 돌리면서 들어오는 값을 전부 검증했지만 문제가 없었기 때문에 참 의아했었지만, 의외로 엉뚱한 곳에서 문제가 생겼었다.

오류 해결

오류의 원인은 Batch Scheduler가 10초마다 돌고 있었고 Batch의 로직이 마지막 로그인 날짜를 기준으로 3일동안 접속하지 않았을 때 휴면유저로 바꾸고 있었다.

 @Bean
  @StepScope
  public JpaPagingItemReader<User> inactiveUserReader(
      @Value("#{jobParameters['timeLimitDays']}") Long timeLimitDays,
      @Value("#{jobParameters['currentDate']}") String currentDateStr) {

    // 기본 비활성 기준 일수 설정 (3일)
    if (timeLimitDays == null) {
      timeLimitDays = 3L;
    }

    // 현재 날짜 설정 (파라미터로 받거나 현재 시간 사용)
    LocalDateTime currentDate = currentDateStr != null ?
        LocalDateTime.parse(currentDateStr) : LocalDateTime.now();

    // 쿼리 파라미터 설정
    Map<String, Object> parameterValues = new HashMap<>();
    parameterValues.put("timeLimit", currentDate.minusDays(timeLimitDays));
    parameterValues.put("activeStatus", UserStatusEnum.ACTIVE_USER);

    // JPA를 사용하여 비활성 사용자를 페이징 방식으로 조회하는 reader 생성
    return new JpaPagingItemReaderBuilder<User>()
        .name("inactiveUserReader")
        .entityManagerFactory(entityManagerFactory)
        .queryString("SELECT u FROM User u WHERE u.lastLoginDate < :timeLimit AND u.status = :activeStatus")
        .parameterValues(parameterValues)
        .pageSize(100)
        .build();
  }

이 부분에서 위의 정상 유저로 바뀌는 로직을 돌려도 로그인 날짜가 변하지 않기 때문에 Batch는 해당 이벤트를 인식하고 계속 휴면 유저로 바꾸고 있었다. 로직의 문제라고 보긴 어렵지만? 설마했던 부분이여서 찾기 어려웠다. 이러한 문제를 인식하고 활성화 로직에서 값을 set 해주는 부분에 localDate를 넣어 계정을 다시 활성화한 날짜로 바꿔줬다.

public void fromInactiveToActive(){
      this.status = UserStatusEnum.ACTIVE_USER;
      this.lastLoginDate = LocalDateTime.now();
  }

0개의 댓글