首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有一种有效的原子方法可以从表中“出队”,并查看它是否为空?

有没有一种有效的原子方法可以从表中“出队”,并查看它是否为空?
EN

Stack Overflow用户
提问于 2020-12-09 02:52:04
回答 1查看 49关注 0票数 0

我有一个表来存储从多个进程访问的SQS队列的状态。它现在的工作方式是将队列中的所有消息添加到表中。每次将队列中的消息出队时,也会将其从表中删除。当表/队列为空时,需要运行一些finalization操作。它目前的实现方式是:

代码语言:javascript
运行
复制
-- dequeue (2 statements so that we can use the primary index for the delete - was seeing a lot of deadlocking otherwise)
BEGIN;
SELECT id FROM messages WHERE messageKey = 'message_key' LIMIT 1 FOR UPDATE;
DELETE FROM messages WHERE id = 'auto_inc_id';
COMMIT;

-- check if it was the last one (shared lock so we know that nobody is currently deleting a message - select count(*) was also causing deadlocks due to locking so many rows)
SELECT * FROM messages LIMIT 1 LOCK IN SHARE MODE;

-- perform finalization if no records returned

不幸的是,这些语句似乎彼此引起了一些争用,这导致了应用程序的缓慢-有没有一种明显的方法可以做到这一点,它仍然是原子的,但需要更少的语句或事务?

该表非常简单,但如果有人感兴趣,我将把它包括在内

代码语言:javascript
运行
复制
CREATE TABLE IF NOT EXISTS `messages` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `messageKey` VARCHAR(256) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
EN

Stack Overflow用户

发布于 2020-12-09 12:00:21

代码语言:javascript
运行
复制
BEGIN;
    SELECT @id := id FROM ... FOR UPDATE;
    IF (@id IS NOT NULL) THEN
        DELETE ... WHERE id = @id;
    END IF;
COMMIT;

然后继续使用@id。

逻辑上有一个缺陷:如果服务器在您使用@id完成之前崩溃,则无法恢复。

如果你想讨论修复这个缺陷,首先回答这个问题:如果你“使用”@id两次,会造成伤害吗?

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65205058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档