mysql - 如果在 MySQL 中同时运行,我的 UPDATE 语句可以工作吗?
问题描述
我看到了许多类似的问题,但我仍然不确定我是否正确。
我们有一个应用程序,它启动一个工作来大量发送许多消息。消息传递状态稍后分批接收,没有特定顺序。
表结构如下:-
CREATE TABLE `message` (
`pk` char(32) NOT NULL DEFAULT '',
`job_id` varchar(40) DEFAULT NULL,
`status` varchar(40) DEFAULT NULL,
`update_date` datetime DEFAULT NULL,
PRIMARY KEY (`pk`),
KEY `job_id` (`job_id`),
KEY `status` (`status`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
最初创建记录时status
设置为 null。它的值预计会从 null 变为sent
,然后变为delivered
。以下语句用于更新记录。
当要设置的状态是 -delivered
Update message SET status = 'delivered', update_date = Now()
WHERE job_id = :someId
当要设置的状态是 -sent
Update message SET status = 'sent', update_date = Now()
WHERE job_id = :someId AND status IS NULL
问题是,可能有两个线程同时尝试将status
同一记录设置为“已发送”和“已交付”。在这种情况下,“已交付”是最终状态,因此我们希望它最终获胜。
上述语句会在 MySql 或 MariaDB 中确保这一点吗?
解决方案
是的,在 MySQL 和 MariaDB(可能还有任何 SQL 数据库)中。对同一行的更新是原子的。
- 'sent' 会覆盖 NULL,但不会 'delivered'
- 'delivered' 将覆盖 NULL 和 'sent'
这就是你想要的。只需确保在更新之前存在具有给定 job_id 的消息 :)
推荐阅读
- javascript - 如果连续单击两个相同的名称,如何使每两个相同的名称保持红色?
- python - 绘制排序数据
- javascript - Javascript对象保留“旧”属性,不能覆盖?
- swift - 如何更改 SpriteKit 中精灵的触摸偏移量?
- python - 在 pytorch 中使用量化模型没有性能提升
- azure - Azure 的 myapps 门户中面向 B2B 用户的聊天机器人
- snowflake-cloud-data-platform - 雪花:为什么在资源争用期间查询会重试两次
- r - 编写我的第一个闪亮的应用程序,如何通过选定的变量进行绘图,为什么这个脚本不起作用?
- python - 如何通过 Pygame 从 MIDI 设备获取输入?
- c++ - 将数据放在私有类中是否理想?(C++)