2016-08-17 118 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