2016-08-17 120 views
0

我想知道是否存在一个真正的案例场景,其中竞争条件问题实际上可能发生在插入查询上。所以我有一个表“用户”具有以下字段:MySQL插入:竞争条件

User: 
iduser | idcompany | name | email 

我使用的是复合主键此表是(ID用户,idcompany)。这些字段均未设置为AUTO_INCREMENT。我通过会话变量获得字段“idcompany”的值,所以在这里没有真正的问题。但是,我使用的是getNextUserId()函数通过这样的选择查询,以获得下一个有效ID用户价值:

SELECT MAX(iduser) + 1 AS next_iduser FROM User WHERE idcompany = {myCompanyId}; 

我不知道是否有任何个案中(ID用户,idcompany)的复制组合可能是插入数据库,因为竞争条件,如果是的话,这种情况如何可能。 MySQL是否在插入时锁定表?不会重复(iduser,idcompany)的简单组合被拒绝,或者我真的可以在我的表中有一个重复的主键?我知道完全防止使用AUTO_INCREMENT主键,使用SQL事务或手动锁定“用户”表的竞争条件的策略,但我想了解在这种情况下可能的竞争条件背后的机制,以及什么是真正的问题这个实现。现在,由于显而易见的原因,这些字段在我的表中都不需要是唯一的,但我想知道对iduser的UNIQUE约束是否会改变我正面临的情况以及为什么会发生这种情况。

+0

它在插入过程中被锁定,但在同一公司的10个用户都尝试注册时不会锁定,而您必须运行SELECT才能找到下一个要使用的ID,而且不会锁定10次。你应该在交易中这样做,但假设你使用的是PDO或MYSQLI,而数据库表是INNODB – RiggsFolly

+1

你可能想看看'SELECT ..... WITH LOCK' [在手册中] (http://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html) – RiggsFolly

+0

正如我在我的问题中明确表示,我不是在寻找解决方案来解决我的问题,我正在尝试了解我的实施可能产生的后果。 Bill Karwin在他的书“SQL反模式”中提到,这种做法会导致竞争条件,因此我试图找出在这种情况下可能出现的情况。 – iiirxs

回答

0

你写过你在iduser,idcompany字段上有一个复合主键。该约束将阻止表具有重复的iduser,idcompany对。没有锁定就可能发生的最糟糕的情况是,违反主键会阻止用户的创建。

+0

因此,即使竞态条件发生,我也永远不会有重复的一对?可以成为我目前的实施方案吗? – iiirxs

+0

有点相关:http://stackoverflow.com/a/6477687 – Drew

+1

这个特定的竞争条件可以通过复合主键(或唯一索引)约束完美地处理。 – Shadow