fix: 修正定时任务调度时间与计划选取逻辑,每天凌晨 1 点执行

master
zangch@mesnac.com 3 weeks ago
parent c3fedce7d5
commit 453f24949d

@ -265,12 +265,12 @@ public class DmsPlanInspectServiceImpl implements IDmsPlanInspectService
}
/**
* 0
* 1
* 使MapperJdbcTemplate
*
* cron
*/
@Scheduled(cron = "0 0 0 * * ?") // 原生产策略:每天 0 点执行
@Scheduled(cron = "0 0 1 * * ?") // 生产策略:每天凌晨 1 点执行
// @Scheduled(cron = "0 * * * * ?") // 测试策略:每分钟执行一次
// @Transactional(rollbackFor = Exception.class)
public void generateDailyInspectWorkOrders() {
@ -278,7 +278,8 @@ public class DmsPlanInspectServiceImpl implements IDmsPlanInspectService
int count = 0;
int skipCount = 0;
try {
// 先把“到期的计划”全部拉出来,后续逐条处理。
// 先把“今天整天内应生成”的计划全部拉出来,后续逐条处理。
// 这里依赖SQL使用“小于次日0点”的上界避免把次日00:00计划提前捞出来。
// 注意:这里不做事务包裹,避免某一条失败影响整批调度。
List<DmsPlanInspect> plans = dmsPlanInspectMapper.selectPendingInspectPlans();

@ -12,6 +12,7 @@ import com.aucma.dms.mapper.DmsPlanMaintMapper;
import com.aucma.dms.service.IDmsBillsMaintInstanceService;
import com.aucma.dms.service.IDmsPlanMaintService;
import com.aucma.quartz.util.CronUtils;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,6 +20,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -313,18 +315,19 @@ public class DmsPlanMaintServiceImpl implements IDmsPlanMaintService {
}
/**
* 0
* 1
* 使MapperJdbcTemplate
*
* cron
*/
@Scheduled(cron = "0 0 0 * * ?")
@Scheduled(cron = "0 0 1 * * ?")
public void generateDailyMaintWorkOrders() {
log.info("========== 开始执行保养工单生成任务 ==========");
int count = 0;
int skipCount = 0;
try {
// 通过Mapper查询今天需要执行的保养计划maint_time <= 今天)
// 通过Mapper查询“今天整天内应生成”的保养计划。
// 这里依赖SQL使用“小于次日0点”的上界避免把次日00:00计划提前捞出来。
List<DmsPlanMaint> plans = dmsPlanMaintMapper.selectPendingMaintPlans();
for (DmsPlanMaint plan : plans) {
@ -343,7 +346,8 @@ public class DmsPlanMaintServiceImpl implements IDmsPlanMaintService {
if (insertRows > 0) {
count++;
log.info("已为保养计划[{}]生成已完成工单", planMaintCode);
// 更新计划的下次执行时间根据cron表达式或默认+1天
// 基于“当前计划时间”推进下次执行时间,
// 避免凌晨1点批量生成当天工单后又把计划推进回当天稍晚时间导致次日被重复捞取。
updateMaintPlanNextTime(plan);
} else {
skipCount++;
@ -372,7 +376,9 @@ public class DmsPlanMaintServiceImpl implements IDmsPlanMaintService {
Date nextTime = null;
String cronExpression = plan.getCronExpression();
if (cronExpression != null && !cronExpression.isEmpty()) {
nextTime = CronUtils.getNextExecution(cronExpression);
// 这里必须基于计划当前 maintTime 推进,而不能基于“当前系统时间”直接算下一次,
// 否则当天未来时点的计划会被错误推进到“今天稍后”,第二天凌晨仍会再次命中。
nextTime = calculateNextMaintTime(cronExpression, plan.getMaintTime());
}
if (nextTime == null) {
log.warn("保养计划下次执行时间计算为null, 使用默认+1天 | planMaintId={}, planMaintCode={}, cronExpression={}",
@ -387,4 +393,25 @@ public class DmsPlanMaintServiceImpl implements IDmsPlanMaintService {
e.getMessage(), e);
}
}
/**
* :
* 1) maintTime
* 2)
*/
private Date calculateNextMaintTime(String cronExpression, Date currentMaintTime) {
try {
CronExpression cron = new CronExpression(cronExpression);
Date now = new Date();
Date cursor = currentMaintTime != null ? currentMaintTime : now;
Date next = cron.getNextValidTimeAfter(cursor);
while (next != null && !next.after(now)) {
next = cron.getNextValidTimeAfter(next);
}
return next;
} catch (ParseException e) {
log.error("cron表达式非法无法计算下次执行时间 | cronExpression={}, 异常信息: {}", cronExpression, e.getMessage(), e);
return null;
}
}
}

@ -160,7 +160,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.cron_expression
FROM dms_plan_inspect a
WHERE (a.is_flag = '1' OR a.is_flag IS NULL)
AND a.plan_time &lt;= TRUNC(SYSDATE) + 1
<!-- 小于次日0点凌晨1点批量生成“今天整天”的工单但不提前捞取次日00:00计划 -->
AND a.plan_time &lt; TRUNC(SYSDATE) + 1
</select>
<!-- 更新巡检计划的下次执行时间 -->

@ -234,7 +234,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.cron_expression
FROM dms_plan_maint a
WHERE (a.is_flag = 0 OR a.is_flag IS NULL)
AND a.maint_time &lt;= TRUNC(SYSDATE) + 1
<!-- 小于次日0点凌晨1点批量生成“今天整天”的工单但不提前捞取次日00:00计划 -->
AND a.maint_time &lt; TRUNC(SYSDATE) + 1
</select>
<!-- 更新保养计划的下次执行时间 -->

Loading…
Cancel
Save