以下の@Scheduled
ように、1 時間ごとに cron 式を使用してSpring をセットアップしました。trend.olap.local.loading.cron.expression
0 0 * * * ?
@Scheduled(cron = "${trend.olap.local.loading.cron.expression}")
public void loadHoulyDataToLocalOlap() {
try {
// To calculate prev hour;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, -1);
Date date = cal.getTime();
int hour = cal.get(Calendar.HOUR_OF_DAY);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Loading hourly data into local olap :" + date
+ ", and hour :" + hour);
}
dataIntegrationProcessor.loadHourlyDataToLocalOlap(hour);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Loading hourly data into local olap :" + date
+ ", and hour :" + hour + " Completed.");
}
} catch (Exception e) {
LOGGER.error("Error occured at loadHoulyDataToLocalOlap", e);
}
}
ここでの目的は、現在の日付と時刻から時間の値を取得し、それをエグゼキューター メソッドに渡すことです。
基本的に、17:00 に時間の値が 16 になるように、現在の時間から 1 を引いています。
しかし、ログを見ると、時間の値は 15 です。これは、スケジューラが 16:59:59,831 頃に実行されたためです。以下の log4j ログを参照してください。cron ジョブがミリ秒単位で四捨五入され、17:00:00,000 の数ミリ秒前にトリガーされているようです。
このため、間違った値を取得しており、ビジネス ケースが失敗しています。
数ミリ秒前ではなく、1 時間ごとに正確に 0 番目のミリ秒で cron を実行するにはどうすればよいですか?
DEBUG 2013-09-29 16:59:59,831 (TrendScheduler.java loadHoulyDataToLocalOlap:57) - Loading hourly data into local olap :Sun Sep 29 15:59:59 IST 2013, and hour :15
DEBUG 2013-09-29 16:59:59,831 (DataIntegrationProcessor.java loadHourlyDataToLocalOlap:57) - Loading hourly data for hour :15
INFO 2013-09-29 17:00:00,054 (KettleJobExecutor.java executeJob:73) - Job (24hr_populate_hour_data_job.kjb) executed successfully
DEBUG 2013-09-29 17:00:00,054 (TrendScheduler.java loadHoulyDataToLocalOlap:64) - Loading hourly data into local olap :Sun Sep 29 15:59:59 IST 2013, and hour :15 Completed.