2013-05-15 28 views
2

我們有一個高性能的Django Web應用程序,它利用MySQL的InnoDB的行級鎖定。在我們的代碼中,我們看到(在進程A中)是否通過使用可以獲得表中的特定行。如果有另一個使用該行的進程(B),並首先到達那裏,那麼該行上將有一個排它鎖,並且A會得到一個「鎖定等待超時」異常。 A會抓住這一點,然後繼續嘗試另一行(使用類似的方法)。如果發生MySQL/InnoDB'鎖定等待超時',那麼鎖定是免費的嗎?

但是,我並不是100%確定發生鎖定等待超時時會發生什麼情況。 B完成並釋放它的鎖之後,即使A的'select ... for update'查詢超時,A會繼續鎖定另一行,是否會給A賦予排它鎖定?

(這是我認爲直覺上發生的事情),在A試圖獲得鎖定失敗後,它繼續前進,B完成並完成:是否沒有進一步嘗試將鎖定給A?

從官方的MySQL文檔中,任何引用/引用都是最好的,因爲它是規範的來源。我無法找到文檔中的任何內容,特別是,它解決了當您嘗試獲取鎖定並超時時發生的情況。

+2

「*有沒有進一步的試圖將鎖定給A *「。我很確定答案是肯定的,但我無法證明。 –

回答

3

由超時發言請求鎖將永遠不會被收購:

When a lock wait timeout occurs, the current statement is rolled back.

下面的測試顯示出這樣一個事實:

-- "atable" is an InnoDB table 

-- Connection #1 
BEGIN; 
UPDATE atable SET acol = 1 WHERE acol = 2; 

-- Connection #2 
BEGIN; 
SELECT * FROM atable FOR UPDATE; -- hangs 

-- Connection #3 
BEGIN; 
SELECT * FROM atable FOR UPDATE; -- hangs 

-- wait until Connection #2 times out 
-- Connection #2 
-- "Lock wait timeout exceeded" 

-- Connection #1 
COMMIT; 

-- Connection #3 resumes execution and data is displayed