MySQL如何定期执行任务
实际项目中需要定期处理业务,比如说会员检查是否过期。mysql可以执行定期任务。下面我就以我写过的一个项目为例,记录mysql如何执行定期任务
项目背景
该项目是记录了用户的会员,自用户注册以来,会员期限是30天,如果用户30天内未订购订单,会员等级就会降低。此功能是需要定期检查会员状态。判断是否过期。我采用的是mysql的事件功能,进行处理。要处理事件,首先得有存储过程,或者函数,这里以存储过程为例。该功能的实现有三步:(这里建议有关事件的操作使用命令操作,如果使用工具,报错我没研究会解决办法)
- 检查mysql是否开始事件功能,使用下面命令查看是否开启事件,如果是OFF表示未开启
show variables like 'event_scheduler';
如果未开启事件,执行开启事件命令
set global event_scheduler = on;
经过上述步骤可以开始事件,但是当数据库服务重启后,事件会自动关闭。需要找到数据库安装目录的my.ini ,里面添加 event_scheduler=ON,就可以了。
2. 创建存储过程(可以使用工具创建,也可以使用命令创建,我这里使用Navicat工具创建的)
CREATE DEFINER=`root`@`localhost` PROCEDURE `member_check`()
BEGIN
/**
声明一个存储过程,判断用户会员是否过期。
如果过期:
1.会员等级降到未到普通会员,将会员等级降低一级,重新规定日期今天至今天之后的30天。
2.会员等级到普通会员。保持普通会员,但是重新规定日期今天至今天之后的30天。
说明:会员等级有5级,1是至尊会员,5是普通会员
*/
#声明当前游标指向的会员ID
DECLARE member_id int;
#声明当前游标指向的会员等级ID
DECLARE grade_id int;
#声明当前游标指向的会员截止时间
DECLARE stop_time datetime;
#声明当前游标指向的当前时间
DECLARE now_time datetime;
#定义游标溢出判断变量
DECLARE done INT DEFAULT 0;
#定义光标
DECLARE curr_row CURSOR FOR SELECT m_id,g_id,m_stop_time,NOW() now from t_member;
#溢出处理,注意一定要声明这句话,否则后面会报错溢出
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
#打开游标
OPEN curr_row;
#循环开始
flag_loop:loop
#提取游标中的数值
FETCH curr_row INTO member_id,grade_id,stop_time,now_time;
#如果溢出,结束循环,如果没有该判断,直接会溢出报错
IF done = 1
THEN LEAVE flag_loop;
ElSE
#循环,执行功能,判断截止时间是否过期
IF ((stop_time-now_time)<0) THEN
#如果会员等级不是普通会员,则降低会员等级1级
IF(grade_id<5) THEN
SET grade_id = grade_id+1;
END IF;
UPDATE t_member SET g_id=grade_id,m_start_time=NOW(),m_stop_time=adddate(now(),30) WHERE m_id=member_id;
END IF;
END IF;
#循环结束
end loop;
#关闭游标
CLOSE curr_row;
END
- 创建一个时间,并开启事件功能
# 创建事件,check_member_over时间名,schedule 后面是执行时间,可以是年,月,日,时,分,秒...
create event if not exists check_member_over
on schedule every 1 DAY
STARTS '2020-04-25 10:00:00'
on completion preserve
do call member_check();
# 开启执行事件
alter event check_member_over on completion preserve enable;
# ===========================另外说明关闭执行事件的语法=============================
alter event check_member_over on completion preserve disable;