Runjob(런잡 프로젝트)/SpringBoot + Kotlin

[SpringBoot + Kotlin] Scheduled DB 의 업데이트 날짜와 비교해서 실행

맏리믓 2023. 4. 24. 17:18

들어가며

- 정보중 정보를 업데이트 한 날짜는 생각보다 중요하다.

- 앞서 진행 한 Scheduled 방식은 서버가 잠시 중단되거나 모종의 이유로 다시 시작되었을때 내가 원하는 대로 돌아가지 않을 수 있다.

- 이러한 상황을 방지 하고자 DB 에 업데이트 날짜와 시간을 기록하고 이와 비교하며 업데이트 하는 것이 좀더 안전하다 볼 수 있다.

- 이번 시간에는 새로 짜면서 글을 쓰기엔 조금 복잡 하니 원래 하던 프로젝트의 코드 일부분을 가져와 설명 하도록 하겠다.


ChkNeedUpdate.kt

- Time 을 포멧팅 해주는 함수

- DB 에 저장 되었던 시간과 현재 시간 사이의 시차를 계산하여 업데이트 할 필요가 있는지 확인해 주는 함수 이다.

- 같은 방식으로 원하는 시간 차이(1초, 10분, 12시간 ...)를 계산 할 수 있다.

package com.threemovie.threemovieapi.Utils

import java.time.Duration.between
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

class ChkNeedUpdate {
   companion object {
      val formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmm")
      
      fun retFormatterTime(): Long {
         return LocalDateTime.now().format(formatter).toLong()
      }
      
      fun chkUpdateOneMinute(reviewTime: Long): Boolean {
         val current = LocalDateTime.now()
         val formatted = LocalDateTime.parse(reviewTime.toString(), formatter)
         
         return between(formatted, current).seconds >= 60
      }
   }
}

UpdateTimeRepository

- 각각의 정보가 업데이트 된 시간을 DB 에 저장 하고 다시 불러오는 Repository 이다.

- 나중에 설명할 query 문으로 저장, 정보를 불러 온다.

package com.threemovie.threemovieapi.Repository.Support

import com.querydsl.jpa.impl.JPAQueryFactory
import com.threemovie.threemovieapi.Entity.QUpdateTime
import com.threemovie.threemovieapi.Entity.UpdateTime
import jakarta.transaction.Transactional
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport
import org.springframework.stereotype.Repository

@Repository
class UpdateTimeRepositorySupport(
   val query: JPAQueryFactory
) : QuerydslRepositorySupport(UpdateTime::class.java) {
   val updateTime: QUpdateTime = QUpdateTime.updateTime
   
   fun getMovieData(): Long = query
      .select(QUpdateTime.updateTime.movieData)
      .from(QUpdateTime.updateTime)
      .fetchFirst()
   
   @Transactional
   fun updateMovieData(newTime: Long): Unit {
      query
         .update(updateTime)
         .set(updateTime.movieData, newTime)
         .execute()
   }
}

실제 사용

- DB 의 업데이트 시간을 가져 온 후  ChkNeedUpdata 를 통해 업데이트 필요 여부를 확인

- 데이터 업데이트 실행

- 업데이트 시간 업데이트 순으로 이루어 진다.

@Async
@Scheduled(cron = "0 0 0/1 * * *")
fun getReview(){
    if (ChkNeedUpdate.chkUpdateTwelveHours(UpdateTimeRepositorySupport.getReviewTime())) {
        movieReviewRepository.truncate()
        movieList = getMovieListDB()
        getReviewLT()
        getReviewMB()
        UpdateTimeRepositorySupport.updateReviewTime(ChkNeedUpdate.retFormatterTime())
    }
}