在一些业务需要中,经常需要一些定时任务。如Java的schedule,nodejs的node-schedule
等。今天第一次接触了使用数据库的存储过程
来执行定时任务。
本篇文章以MySQL数据库为例,介绍通过数据库设置定时任务的方法。本文中以介绍操作过程为主,具体的sql语句、调用方法等,会因为业务需求的不同各不相同,具体方法和扩展使用可以自行查阅。
简介
数据库执行定时任务主要涉及三个过程:存储过程、事件和任务执行。如下图:没有定义存储过程和事件的数据库中,这两个文件夹下内容为空;而定义了存储过程和事件的数据库如图中所示。
第一步:定义存储过程
CREATE DEFINER=`dbname`@`%` PROCEDURE `dbname`.`dbtable_expires`()
BEGIN
set @expired_id = (select id from ac_id_table ac where expire_at < now() limit 1);
insert into ac_expires_events_result(id) values (@expired_id);
update ac_id_table set flag=0 where id = @expired_id;
update ac_id_associate set status=0 where id = @expired_id;
END
说明:
- 通过
CREATE DEFINER=`dbname`@`%` PROCEDURE `dbname`.`dbtable_expires`()
语句定义一个存储过程 BEGIN
和END
之间是执行事件的语句。在本例中,包括:- 从表格里面筛选符合条件的数据,并写入
ac_expires_events_result
表 - 将
ac_id_table
表中符合条件的flag
更新为0 - 将
ac_id_associate
表中符合条件的数据的status
字段更新为0
- 从表格里面筛选符合条件的数据,并写入
这样,一个存储过程就定义完成。
第二步:定义和执行事件
CREATE EVENT id_expires_event // 定义事件
ON SCHEDULE EVERY 1 MINUTE // 每分钟执行一次
STARTS '2023-11-07 11:13:48.000' // 开始于什么时候
ON COMPLETION NOT PRESERVE // 当单次计划任务执行完毕后或当重复性的计划任务执行到了
DISABLE ON SLAVE
DO call dbname.dbtable_expires() // call 存储过程定义的名称
说明:
CREATE EVENT client_expires_event
定义事件ON SCHEDULE EVERY 1 MINUTE
每分钟执行一次STARTS '2023-11-07 11:13:48.000'
开始于什么时候ON COMPLETION NOT PRESERVE
当单次计划任务执行完毕后或当重复性的计划任务执行到了DO call dbname.dbtable_expires()
调用定义的存储过程。这里需要特别注意:此处DO call
的dbname.dbtable_expires()
就是第一步中定义的存储过程的名称
第三步:执行存储过程
定时任务的最后一步是执行存储过程。使用的命令如下:
call dbname.dbtable_expires(); #执行存储过程
该命令用于手动执行一次事件,定时执行还需要通过如下命令,全局开启定时任务调度器。执行下列命令后,就可以定时执行任务。PS:全局开启调度器需要有数据库管理员权限才行~
SET GLOBAL event_scheduler = 1; #全局开启调度器
另外,还有如下命令,可以查看创建事件、查看调度器状态。
show events; # 查看已创建的时间
show variables like '%scheduler%'; #查看调度器状态