[Quartz] Spring xml Re-Schedule When Fail

S_H_H·2022년 10월 5일
0

Quartz And Batch

목록 보기
4/8

재 실행?

로직의 문제가 아닌 외부적인 요인으로 인하여, Batch가 실패 했을 떄 재 실행을 원할 경우가 있을 것이다.
재 실행을 몇 분뒤 혹은 스케줄러로 관리를 하고 싶다면 다음과 같은 방법을 사용하면 됩니다.

바로 재 실행을 원한다면 `RefireImmediately`를 사용하시면 됩니다.

이건 제가 뚝딱 거리면서 한 방법이라 다른 좋은 방법도 있습니다


Job 실행 시 JobDataapplicationContext의 정보를 넣고,
필요시 현재 실행 중인 스케줄러에 대한 정보를 수정하여 재 실행이 가능하도록 구현했습니다.

재 실행이 필요한 Job에 applicationContextJobDataKey을 추가합니다.

  <bean id="testExcueteJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="실행할 service"/>
    <property name="applicationContextJobDataKey" value="applicationContext"/> <-- 추가
  </bean>

실패 시 error로 파악하기 위해 try catch를 사용했습니다.

	@Autowired
	private ApplicationContext applicationContext;

    protected void testJob(JobExecutionContext context) throws JobExecutionException{

        try {
        	applicationContext = (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");
        	testJobService.reStartTest();
        } catch (Exception e) {
            try {
            	reStartScheduleJob();
            } catch (SchedulerException e1) {
				//e1
			}
        }
    }

이후 5분뒤 실행을 하기 위해 SimpleDateFormat을 이용해 cron 형식의 스케줄러를 만들었습니다.
-> 5분뒤라는 간단한 형식의 cron 형식이라 SimpleDateFormat을 사용했지만 복잡한 경우 CronSequenceGenerator을 이용하면 됩니다.

    private void reStartScheduleJob() throws SchedulerException
    {
    	//시간 설정
    	SimpleDateFormat dateFormat = new SimpleDateFormat( "0 mm HH dd MM ? yyyy");
    	Calendar cal = Calendar.getInstance();
    	Date date = new Date();

    	cal.setTime(date);
    	cal.add(Calendar.MINUTE, 5);
    	String startTriggerDate = dateFormat.format(cal.getTime());
    	//필요한 데이터 저장
    	JobDataMap jobData = new JobDataMap();
    	jobData.put("applicationContext", applicationContext);

    	//job 생성
    	JobDetail job = newJob(testExcueteJob.class)
    			.withIdentity("testExcueteJob",Scheduler.DEFAULT_GROUP)
    			.setJobData(jobData)
    			.build();

    	//실행할 trigger 생성
    	Trigger trigger = newTrigger()
    			.withIdentity("testExcueteJob",Scheduler.DEFAULT_GROUP)
    			.withSchedule(cronSchedule(startTriggerDate))
    			.build();

        scheduler.scheduleJob(job, trigger);
        scheduler.start();

    }

처음 실행했던 Job과 동일하게 JobDataMapapplicationContext을 넣어줍니다.
그리고 JobDetail Trigger을 만들어준 후 scheduler에 등록을 합니다.
위와 같이 실행하면 error가 발행 하면 5분뒤에 실행이 되는 스케줄러가 만들어졌습니다.


하지만 더 고안할 부분이 많은데요
계속해서 error가 발생 할 경우 끝임없이 5분뒤에 실행이 됩니다. 몇 번 재 실행할지 설정이 필요합니다.
-> JobDataMap에 재 실행 변수 값을 넣어 관리하는 방법도 있습니다.

profile
LEVEL UP

0개의 댓글