我已经为 Spring 的 @Scheduled
设置了每小时的 cron 表达式,如下所示,其中 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。
但是如果您查看日志,小时值为 15。这是因为调度程序在 16:59:59,831 左右运行。请参阅下面的 log4j 日志。看起来 cron 作业正在四舍五入毫秒,并在 17:00:00,000 之前的几毫秒被触发。
因此,我得到了错误的值(value)观,我的商业案例失败了。
如何让 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.
最佳答案
简短的回答是您不能使用 cron
选项。 cron 表达式的精度是秒,所以它会四舍五入到最接近的秒。您可以保证它至少在特定时间之后发生,但不完全是 cron。
您最好的选择是实现您自己的 Trigger
。 Trigger
接口(interface)有一个返回下一次执行的 java.util.Date
的方法(以毫秒为单位)。从那里您可以注册任务和触发器,如此处的文档所示:http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableScheduling.html
关于java - Spring 的 @Scheduled cron 作业在预定时间前几毫秒触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19078313/