您的位置:

MySQL定时任务的实现

一、MySQL定时任务生成表


CREATE TABLE `task_schedule` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '任务ID',
  `task_name` varchar(255) NOT NULL COMMENT '任务名称',
  `task_detail` varchar(255) DEFAULT NULL COMMENT '任务详细描述',
  `task_cron` varchar(255) NOT NULL COMMENT '任务执行时间表达式',
  `task_command` varchar(255) NOT NULL COMMENT '任务执行的命令或SQL语句',
  `task_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '任务状态,1表示启用,0表示禁用',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务调度表';

首先,我们需要创建一个任务调度表(task_schedule),该表用于存储需要定时执行的任务。表结构如上所示,其中task_name、task_detail、task_cron和task_command字段分别为任务名称、任务详情描述、任务执行时间表达式(类似linux中的cron表达式)和任务执行的命令或SQL语句。我们需要定时查询该表,并根据task_cron字段来判断是否需要执行对应的任务。

二、MySQL定时更新数据


UPDATE task_schedule SET task_status = 0 WHERE task_cron = '0 0 1 * * *';

使用MySQL定时更新数据十分常见,可以根据需要设置相应的更新时间点和更新的SQL语句。例如上面的例子表示每月1号凌晨0点0分0秒执行一次,将task_status字段设置为0。

三、MySQL定时任务每天固定时间执行


CREATE EVENT `daily_task`
ON SCHEDULE EVERY 1 DAY STARTS '2022-01-01 00:00:00'
DO BEGIN
    UPDATE user SET points = points + 10 WHERE user_type = 'daily';
    INSERT INTO log (user_id, points) SELECT id, 10 FROM user WHERE user_type = 'daily';
END;

MySQL提供了事件调度器,可以通过事件来实现每天固定时间执行任务的功能。上面的代码演示了每天0点0分0秒执行一个任务,将user表中user_type字段为daily的用户的points字段加10,并将相应的操作记录插入到log表中。

四、Oracle定时任务SQL


BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
    job_name        => 'send_sales_reports',
    job_type        => 'STORED_PROCEDURE',
    job_action      => 'ops.send_sales_reports_proc',
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'FREQ=HOURLY;INTERVAL=2',
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Job to send sales reports every 2 hours');
END;

Oracle数据库也提供了调度器,可以通过CREATE_JOB来创建定时任务。上述代码表示创建一个每两个小时执行一次的任务,调用ops.send_sales_reports_proc存储过程。

五、MySQL定时清理数据


CREATE EVENT `clean_history_data`
ON SCHEDULE EVERY 1 MONTH STARTS '2022-01-01 00:00:00'
DO BEGIN
    DELETE FROM history_data WHERE create_time < DATE_SUB(NOW(), INTERVAL 6 MONTH);
END;

我们也可以使用MySQL的事件调度器来实现定时清理数据的功能。上面的代码表示每月1号0点0分0秒执行一次,删除history_data表中创建时间早于当前时间6个月的数据。

六、MySQL定时器


DELIMITER $$
CREATE PROCEDURE `check_order_status`()
BEGIN
    DECLARE done BOOLEAN DEFAULT FALSE;
    DECLARE order_id INT(11);
    DECLARE cursor_order CURSOR FOR SELECT id FROM `order` WHERE status = 'processing';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
 
    OPEN cursor_order;
 
    order_loop: LOOP
        FETCH cursor_order INTO order_id;
        IF done THEN
            LEAVE order_loop;
        END IF;
 
        UPDATE `order` SET status = 'timeout' WHERE create_time < DATE_SUB(NOW(), INTERVAL 30 MINUTE) AND id = order_id;
 
    END LOOP;
 
    CLOSE cursor_order;
 
END$$
DELIMITER ;
 
SET GLOBAL event_scheduler = ON;
 
CREATE EVENT `check_order_status_event`
ON SCHEDULE EVERY 1 MINUTE STARTS NOW()
DO CALL `check_order_status`();

MySQL定时器也是常见的定时任务实现方式之一。上述代码演示了一个定时器的作用,每1分钟执行一次check_order_status存储过程,根据条件查询order表中的订单数据,将订单状态更新为timeout。通过定时器,可以实现各种不同类型的定时任务。