前段时间完成了一个按照当前时间自动修改会议状态的需求,需求如下:会议存在三个状态:预约成功(会议未开始),会议进行中,会议已经结束。按照产品部门的要求,此状态为自动改变,非人为处理。对于数据量较小的环境下,按照当前时间与会议开始、结束时间进行对比,使用java的Timer定时工具或者使用Schedule等,每间隔指定的一段时间去数据库查询当前的会议开始与结束时间并与当前时间已经对比,很容易就可以完成会议状态的修改。代码如下:
@Configuration
@Slf4j
public class AutoStopMeeting {
@Autowired
private MeetingCreateMapper meetingCreateMapper;
//固定时间 每间隔10s执行一次
@Scheduled(fixedDelay = 1000*10)
public void checkTime(){
System.out.println("定时任务执行了1");
try{
//查询meeting_create中的时间,查看当前时间是否已经超过了endTime,如果已经超过了则设置当前的
//meetingStatus的状态为已经结束:3
Date date = new Date();
List<MeetingCreate> list= meetingCreateMapper.selectEndTime();
if(list.size()!=0){
//遍历查询出来的实体的信息
for(MeetingCreate meetingCreate:list){
if( meetingCreate.getEndtime().getTime()<date.getTime()){
System.out.println("定时任务执行了3");
Integer id = meetingCreate.getId();
System.out.println("此时的id是"+id);
int update=meetingCreateMapper.updateMeetingStatusAuto(id,3);
System.out.println("定时任务执行了4");
System.out.println("update"+update);
if(update==1){
//更新会议状态成功
log.info("checkTime==>当前时间已经超过会议预约时的结束时间,会议自动结束");
}else{
log.error("checkTime==>会议结束失败,请联系管理员");
break;
}
}else if (date.getTime()<meetingCreate.getEndtime().getTime()&
date.getTime()>meetingCreate.getBegintime().getTime()){
Integer id = meetingCreate.getId();
int update=meetingCreateMapper.updateMeetingStatusAuto(id,4);
if(update==1){
//更新会议状态成功
log.info("checkTime==>当前时间为已经预约的会议期间,会议状态自动设置为正在进行中");
}else{
log.error("checkTime==>会议状态更新失败,请联系管理员");
break;
}
}
}
}
}catch(Exception e){
log.error("checkTime失败==>"+e);
}
}
}`
因为用户量较小,同时也在mapper.xml文件中对筛选的条件作了限制,每次修改或者查询的数据并不是很大,所有此代码完成这个任务时没有问题的。
但是考虑到后续的用户量增多产生的代码重构等的问题点,在下一个需求中我想换一种更为简单的方式,在查询了资料过后使用到了MySQL存储过程中的定时任务。
数据库存储过程 + 定时任务有以下两个特点:
优点:代码量少,低延迟,更新结果速度快
缺点:对不熟悉存储过程的人编写不友好
2.数据库定时任务:
1、查看定时策略是否开启
查看命令
show variables like '%event_sche%';
显示的event_scheduler为OFF时用以下命令开启
set global event_scheduler=1;
注意:以上的改法在数据库重启后将会恢复为原来状态,要想数据库重启后也可以让event_scheduler开启,则需要在配置文件my.ini的设置。修改如下,然后重启mysql服务即可。
[mysqld]event_scheduler=ON //
这一行加入mysqld标签下
2 . sql 代码块
新建函数,将过程命名为UPDATE_STATUS
BEGIN
#Routine body goes here...
#状态(1:待推送,2:正在推送中,3:推送结束)
update message_push set messageStatus = 1 where beginTime >= NOW();
update message_push set messageStatus = 2 where beginTime <= NOW() AND endtime >= NOW();
update message_push set messageStatus = 3 where endTime <= NOW();
END
- 定时任务
新建事件,调用我们刚刚创建的函数,设置从2020-08-28 15:19:05开始执行上述函数操作,每隔60s执行一次
可以尝试向数据库新增数据,并检验以上设置是否生效,谨以此记录我的踩坑过程