【发布时间】:2016-08-17 13:39:04
【问题描述】:
我想知道是否存在在插入查询中实际发生竞争条件问题的真实案例。所以我有一个包含以下字段的“用户”表:
User:
iduser | idcompany | name | email
我为此表使用复合主键 (iduser, idcompany)。这些字段均未设置为 AUTO_INCREMENT。我通过会话变量获取字段“idcompany”的值,因此这不是真正的问题。但是,我使用 getNextUserId() 函数通过这样的选择查询获取下一个有效的 iduser 值:
SELECT MAX(iduser) + 1 AS next_iduser FROM User WHERE idcompany = {myCompanyId};
我想知道是否存在由于竞争条件而在数据库中插入 (iduser, idcompany) 的重复组合的任何情况,如果是,这种情况如何可能。 MySQL在插入时不会锁定表吗? (iduser, idcompany) simple 的重复组合不会被拒绝,或者我的表中真的可以有一个重复的主键吗?我知道完全防止竞争条件的策略,例如使用 AUTO_INCREMENT 主键、使用 SQL 事务或手动锁定“用户”表,但我想了解在这种情况下可能的竞争条件背后的机制以及真正的问题是什么这个实现。现在,出于显而易见的原因,这些字段在我的表中都不需要是唯一的,但我想知道例如对 iduser 的 UNIQUE 约束是否会改变我面临的场景以及为什么会发生这种情况。
【问题讨论】:
-
它在插入期间锁定,但在同一公司的 10 个用户都尝试注册并且您必须运行 SELECT 以找到下一个 ID 以使用 10 次时没有锁定。您确实应该在事务中执行此操作,但假设您使用的是 PDO 或 MYSQLI 并且数据库表是 INNODB
-
你不妨看看
SELECT..... WITH LOCKhere in the manual -
这与@RiggsFolly 的评论有关。使用intention lock。没有人会明智地使用 max。
-
@RiggsFolly 我对这个问题的解释是 OP 想要理解某个设计的含义。该问题清楚地表明,OP 知道其他解决方案来避免这种竞争条件。
-
@RiggsFolly 在最后一段中有多个问题。或许你可以制定一个答案。
标签: mysql database insert race-condition composite-primary-key