【问题标题】:How can I prevent a stored procedure from running twice at the same time?如何防止存储过程同时运行两次?
【发布时间】:2021-03-20 01:54:05
【问题描述】:

我使用 Aurora DB(即 MySQL 5.6.10 版)作为队列,并且使用存储过程从表中批量提取记录。存储过程按以下步骤工作...

  1. 选择下一批数据放入临时表中
  2. 将临时表中记录的 ID 写入日志表中
  3. 输出记录

一旦将一条记录添加到日志中,下次调用时sproc就不会再次选择它,因此多个服务器可以调用这个sproc,并且都可以处理队列中的批量数据而不会互相踩脚.

存储过程在几分之一秒内运行,但我的公司现在正在自动启动服务器,这些克隆的服务器在恰好同时调用存储过程,结果是一样的记录被选择了两次

有没有办法可以让这个存储过程一次只能调用一次?理想情况下,任何额外的调用都应该等到第一个调用完成,然后它们才能运行

不幸的是,我很少有使用 MySQL 的经验,所以我不确定从哪里开始。如果有人能指出正确的方向,我将不胜感激

【问题讨论】:

  • 将数据库用作队列是一种成本高昂的解决方案。我建议您改用真正的队列服务。亚马逊有一个:SQS
  • 我们确实考虑过这一点,但 SQS 也有一些相当大的成本。不过谢谢你的建议。如果我们的应用程序继续增长,我们可能会重新审视它

标签: message-queue amazon-aurora


【解决方案1】:

这是MySQL table locking 的工作。尝试这样的事情。 (您没有向我们展示您的查询,所以这里有很多猜测。)

SET autocommit = 0;
LOCK TABLES logtable WRITE;
CREATE TEMPORARY TABLE temptable AS 
        SELECT whatever FROM whatevertable FOR UPDATE;
INSERT INTO logtable (id) 
          SELECT id FROM temptable;
COMMIT;
UNLOCK TABLES;

如果多个连接尝试同时运行此序列,一个将等待另一个的UNLOCK TABLES; 继续。你说你的 SP 很快,所以可能没有人会注意到短暂的等待。

专业提示:当您在许多服务器上运行相同的定时代码时,最好在运行作业之前设置一个短暂的随机延迟。这样一来,共享资源(例如您的 MySQL 数据库)就不会受到大量精确定时为同时的请求的影响。

【讨论】:

  • 谢谢,这看起来正是我所追求的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
  • 2023-03-13
  • 2016-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多