前提
最近在使用定时任务接受历史数据,我设置quartz的定时任务是每五分钟通过接口查询数据,然后插入数据库,但是后面通过数据比对发现我大概每100条数据会丢失10条左右,然后我很奇怪,去查看数据库,进行数据比较,发现我每小时都会丢失5分左右的数据,都会在每小时的最后的五分钟没有数据插入;
问题思考
首先我以为我job的cron表达式错误,然后我的表达式是 "0 */5 * * * ?" ,检查没有问题;
然后我以为是出现bug了,然后去检查日志文件,发现也没有日志文件产出
然后我去检查我的代码,因为数据丢失的极为有规律,检查发现,问题源自于我的时间计算,我用的是Calendar的roll方法来计算前五分钟,不是整点的时候计算都没有问题,当是整点的时候,计算就有问题了,于是我敲了个小demo验证
问题发现
//DateUtil是我自己写的时间转换工具类,用来字符串和Date的转换
Date date = DateUtil.formatStringToDate("2019-03-01 11:00:00");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
//calendar.roll(Calendar.SECOND, -1);//当时间为整点的时候,倒退一秒,输出 2019-03-01 11:00:59
//calendar.roll(Calendar.MINUTE, -1);//当时间为整点的时候,倒退一分钟,输出 2019-03-01 11:59:00
//calendar.roll(Calendar.DAY_OF_MONTH, -1);//当时间为某月第一天的时候,输出2019-03-31 11:00:00
//calendar.roll(Calendar.DAY_OF_YEAR, -1);//当时间为某月第一天的时候,输出2019-02-28 11:00:00
//calendar.roll(Calendar.MONTH, -4);//当时间为3月,回滚4个月,输出2019-11-01 11:00:00
由上面可知roll是有范围的,他只会在他的范围内变化,不会影响其他范围的变化,比如设置为Calendar.SECOND,他可以在0~59的范围内变化,但是不会影响MINUTE的变化,所以在使用的时候我们得小心使用
问题解决
不使用roll方法,而使用add方法,问题就解决了