如果 运行 同时在 MySQL 中,我的 UPDATE 语句可以工作吗?
Can my UPDATE statements will work if run concurrently in MySQL?
我看到了很多类似的问题,但我仍然不确定我是否完全正确。
我们有一个应用程序可以启动一个作业来批量发送多条消息。消息传递状态稍后分批接收,无特定顺序。
table 结构如下:-
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
设置为 'sent' 和 'delivered'。在这种情况下,'delivered' 是最终状态,因此我们希望它最终获胜。
以上陈述是否会在 MySql 或 MariaDB 中确保这一点?
Update message SET status = 'delivered', update_date = Now()
WHERE job_id = :someId
AND status = 'sent' -- add this??
(MySQL和MariaDB在这方面应该没有区别。)
Update message SET status = 'sent', update_date = Now()
WHERE job_id = :someId
AND status != 'delivered';
是的,在 MySQL 和 MariaDB 中(可能还有任何 SQL 数据库)。
对同一行的更新是原子的。
- 'sent' 将覆盖 NULL,但不会覆盖 'delivered'
- 'delivered' 将覆盖 NULL 和 'sent'
这就是你想要的。在更新之前确保给定 job_id 的消息存在 :)
我看到了很多类似的问题,但我仍然不确定我是否完全正确。
我们有一个应用程序可以启动一个作业来批量发送多条消息。消息传递状态稍后分批接收,无特定顺序。
table 结构如下:-
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
设置为 'sent' 和 'delivered'。在这种情况下,'delivered' 是最终状态,因此我们希望它最终获胜。
以上陈述是否会在 MySql 或 MariaDB 中确保这一点?
Update message SET status = 'delivered', update_date = Now()
WHERE job_id = :someId
AND status = 'sent' -- add this??
(MySQL和MariaDB在这方面应该没有区别。)
Update message SET status = 'sent', update_date = Now()
WHERE job_id = :someId
AND status != 'delivered';
是的,在 MySQL 和 MariaDB 中(可能还有任何 SQL 数据库)。 对同一行的更新是原子的。
- 'sent' 将覆盖 NULL,但不会覆盖 'delivered'
- 'delivered' 将覆盖 NULL 和 'sent'
这就是你想要的。在更新之前确保给定 job_id 的消息存在 :)