【问题标题】:MySQL: Schedule event 15 minutes after table insertMySQL:在表插入后 15 分钟安排事件
【发布时间】:2021-05-06 15:05:11
【问题描述】:
在我的预订数据库中,有一个 RentOrder 表和一个 orderStatus 列。用户可以通过预订 api 访问和下订单。
我希望 MySQL 在初始 RentOrder 插入后等待 15 分钟,并检查 orderStatus 是否仍设置为 RESERVED(即检查订单是否尚未确认)。如果是这种情况,那么我想自动将 orderStatus 设置为TIMEOUT。
到目前为止,我的想法是用户 AFTER INSERT 和 SLEEP,但我不确定这是最优的吗?我主要担心SLEEP 可能会对性能或其他任何方面产生一些不利影响。
欢迎提出任何建议并提前致谢。
【问题讨论】:
标签:
mysql
sql
spring-boot
【解决方案1】:
您可以设置一个事件。就个人而言,我为此目的推荐一个视图:
create view v_RentOrder as
select . . .,
(case when createdAt < now() - interval 15 minute and orderStatus = 'RESERVED'
then 'TIMEOUT'
else orderStatus
end) as orderStatus
from RentOrder;
createdAt 列是记录的创建时间。
瞧!对于使用该视图的任何人,数据始终是最新的 - 到第二个。
您可以将此与定期(例如每天一次或每小时一次)以所需状态更新表格的作业配对。
为每次更新创建事件或作业的选项存在挑战:
- 如果数据库出现故障,更新可能不会生效。
- 如果服务器负载过重,更新可能会延迟。
- 如果表或行被锁定,更新可能会延迟。
-
updates 会增加系统负载并可能干扰其他活动。
这些问题可以通过使用队列/消息系统进行更新来缓解。然而,对于一个简单的问题,这开始变得复杂。
【解决方案2】:
创建以安全时间粒度(例如,每 10 秒)触发的事件过程,并根据需要更新符合您条件的行。
到目前为止,我的想法是用户在插入和睡眠之后
永远不要这样做。触发代码必须尽可能快。如果触发器包含SLEEP(x),那么每一行将花费x 秒进行插入。
CREATE TABLE test (id int);
-- no trigger, fast insertion
SELECT CURRENT_TIMESTAMP(3) INTO @CURRENT_TIMESTAMP;
INSERT INTO test VALUES (1);
SELECT TIMEDIFF(CURRENT_TIMESTAMP(3), @CURRENT_TIMESTAMP)
| TIMEDIFF(CURRENT_TIMESTAMP(3), @CURRENT_TIMESTAMP) |
| :------------------------------------------------ |
| 00:00:00.002000 |
CREATE TRIGGER tr_bi BEFORE INSERT ON test
FOR EACH ROW
SELECT NEW.id + SLEEP(2) INTO @tmp;
CREATE TRIGGER tr_ai AFTER INSERT ON test
FOR EACH ROW
SELECT NEW.id + SLEEP(3) INTO @tmp;
-- 2 triggers with SLEEP, over 2+3=5 second per row insertion
SELECT CURRENT_TIMESTAMP(3) INTO @CURRENT_TIMESTAMP;
INSERT INTO test VALUES (1);
SELECT TIMEDIFF(CURRENT_TIMESTAMP(3), @CURRENT_TIMESTAMP)
| TIMEDIFF(CURRENT_TIMESTAMP(3), @CURRENT_TIMESTAMP) |
| :------------------------------------------------ |
| 00:00:05.003000 |
db小提琴here