MySQL查询语句冲突

时间:2017-11-19 12:51:21

标签: mysql

考虑以下MySQL表,我们将其命名为MyTable

-------------------
| Id | AssignedTo |
-------------------
| 1  | NULL       |
| 2  | NULL       |
| 3  | NULL       |
-------------------

假设我有一个脚本,在访问时会执行以下查询:

UPDATE MyTable SET AssignedTo = '@userid' WHERE AssignedTo IS NULL LIMIT 1

脚本的目的是从特定表中为用户分配id。是否有可能,如果上述脚本在同一时间被两个不同的用户调用,其中一个遗骸没有分配的ID,因为两个MySQL语句相互覆盖?

2 个答案:

答案 0 :(得分:1)

  

是否有可能,如果上述脚本在同一时间由两个不同的用户调用,其中一个遗骸没有分配的ID,因为两个MySQL语句相互覆盖?

没有。 SQL中的各个查询由服务器执行,就像它们被序列化一样:就像在下一个开始之前完成一样。

但请注意:当您使用LIMIT而不使用ORDER BY时,SQL选择的行是不可预测的。它选择它想要的任何行。 不可预测的就像随机但更糟糕的是:随机通常意味着它可能每次都选择不同的行。 SQL世界中的不可预测的意味着它每次选择相同的行,直到它在您的应用程序投入生产后一年没有

另外要注意:如果没有保留NULL值的行,问题中的SQL将默默无效。

答案 1 :(得分:0)

即使它没有在同一时间运行,该查询本身并不能保证所有未分配的行都将被分配。它明确地将自己限制为仅更新一行。

如果,通过 任何 情况,您在任何给定时刻都有AsssignedTo IS NULL多行,您将只分配其中一行(任意选择) )。

基于您在那里显示的一个查询,没有明显的解决方案。是否适合删除LIMIT 1并分配 所有 未分配的行?这意味着如果两个人同时更新,其中一个(任意)将被分配给所有行。那可能不太好。

更好的解决方案会考虑将NULL首先写入数据库时​​发生的情况,或者是否有其他逻辑用于明确选择要分配的未分配行,而不仅仅是'WHERE AssignedTo IS NULL`。