新建一张临时表,当执行定时器的时候去表里查看是是否今天执行过任务。
执行完毕后修改状态,所以其他的表来修改的时候去来确认任务是否执行
一、代码
private static String serverIp = null;
static {
//获取服务器的IP地址,便于后续追踪
try {
InetAddress address = InetAddress.getLocalHost();
serverIp = address.getHostAddress();
} catch (Exception e) {
logger.error("获取服务器IP地址有误!!");
e.printStackTrace();
}
}
/**
* 每日凌晨1点执行
*/
@Scheduled(cron = "0 0 1 * * ?")
public void xxxSchedule(){
logger.info("job start");
String jobName = "xxx";
long startTime = new Date().getTime();
try {
if (canExecute(jobName)){
jobMapper.xxxSchedule();
jobMapper.updateJobStatus(jobName,serverIp,"off");
logger.info(jobName+"执行完成,耗时:"+(new Date().getTime()-startTime)+"毫秒!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private Boolean canExecute(String jobName) throws Exception {
int max = 10000;
int min = (int) Math.round(Math.random()*8000);
long sleepTime = Math.round(Math.random()*(max-min));
logger.info(jobName+"睡了:"+ sleepTime + "毫秒");
Thread.sleep(sleepTime);
if (jobMapper.getJobOff(jobName) == 1){
jobMapper.updateJobStatus(jobName,serverIp,"on");
return true;
}
logger.info(jobName+"已被其他服务器执行");
return false;
}
二、数据库表
CREATE TABLE `job_manager` (
`job_name` varchar(50) NOT NULL PRIMARY KEY COMMENT '名称',
`job_desc` varchar(50) COMMENT 'job描述',
`server_ip` varchar(50) NOT NULL COMMENT '服务器ip',
`on_off` varchar(10) DEFAULT 'off' COMMENT '开关(on:正在执行,off:执行完毕)',
`update_date` datetime NOT NULL COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='job管理' ROW_FORMAT=DYNAMIC;
INSERT INTO `job_manager`
VALUES
('xxx','更新xxx的job','0.0.0.0','off',now());
三、查询或改状态的sql
如下sql中:on_off = 'off' AND update_date < curdate(),是可执行job的标志
<select id="getJobOff" parameterType="string" resultType="int">
SELECT count(1) FROM job_manager
WHERE job_name = #{jobName} AND on_off = 'off' AND update_date < curdate()
</select>
<update id="updateJobStatus" parameterType="map">
UPDATE job_manager
SET on_off=#{status},server_ip=#{serverIp},update_date=now()
WHERE job_name = #{jobName}
</update>