我看到许多类似的问题,但我仍然不能完全确定我是否正确。
我们有一个应用程序,它启动一个作业来批量发送许多消息。消息传递状态稍后将分批接收,并且不按特定顺序接收。
表结构是like:-
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更改为 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中能保证这一点吗?
3条答案
按热度按时间w1e3prcc1#
(mysql和mariadb在这方面应该没有区别。)
uurity8g2#
是的,在mysql和mariadb中(可能还有任何sql数据库)。对同一行的更新是原子的。
“sent”将覆盖null,但不覆盖“delivered”
“delivered”将覆盖null和“sent”
这就是你想要的。在更新之前,请确保具有给定作业id的消息存在:)
2exbekwf3#