我有一张名为席位的桌子,其架构如下
id,taken
对于每个用户,我随机选取一个未采取的 id 并分配给该用户,这里为简单起见,我将采取 =1。我正在使用的查询
update seats u inner join (
SELECT id from seats
where taken is null limit 1) s
on s.id = u.id set taken = 1;
该查询采用随机席位,且采取的标志为 null,并且对于该席位,它使标志为 1。虽然该查询工作正常,但该线程安全吗?
考虑这种情况,我有两个并行用户。对于 user1,我选择行 X,就在运行更新查询之前,user2 签入,并且对于该用户,选择查询返回与 user1 相同的行。所以我将结束更新同一行两次。
此查询可以实现这种情况吗?
使用 mysql,有一个简单的、几乎令人难以置信的解决方案:
update seats set taken = 1
where taken is null
limit 1
此语法将受更新过程影响的行数限制为 1,使用 mysql 对更新语法的特殊扩展来实现您的意图。
当然,作为官方支持的扩展,这是一个原子操作并且完全线程安全。
尽管您的代码和问题都表明无法捕获whichid 已更新,您可以通过用户定义的变量捕获它:
update seats set
taken = 1,
id = (@id := id)
where taken is null
limit 1;
select @id id;
从 select 返回的值要么是已更新的 id,要么是 null(如果没有更新行)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)