2010-12-15 63 views
0

我正在使用SELECT...FOR UPDATE查詢來鎖定表。不幸的是,我有一個情況我需要鎖定兩個不同的行集在同一個表,像這樣:鎖定同一個表兩次

SELECT * FROM mytable WHERE attribute1 = 'something' FOR UPDATE 
SELECT * FROM mytable WHERE attribute2 = 'somethingelse' FOR UPDATE 
UPDATE mytable SET attribute2 = 'somethingnew' WHERE somethingelse 

我需要鎖定的兩套行。我所做的是確保表格中的所有對象都不處於特定狀態,然後查找可以放入該狀態並將其放置在其中的其他對象。目標是滿足某些過於複雜的約束,無法編碼到MySQL中。

所以......問題是,當我在同一個事務中的相同表中兩次出現兩次時會發生什麼?第一把鎖是否被釋放?我已經看到證據證明情況是這樣,但我無法弄清楚如何確認。

+0

您是否在發出SELECT之前將autocommit設置爲0或啓動事務? – outis 2010-12-15 15:58:13

回答

0

如何像

SELECT * FROM mytable WHERE attribute1 = 'something' 
    or attribute2 = 'somethingelse' FOR UPDATE 

UPDATE mytable SET attribute2 = 'somethingnew' WHERE somethingelse 

我不知道直接的回答你的問題,但MySQL手冊說,鎖定了一個發佈在交易完成後(COMMITED或回滾),這意味着第二選擇不釋放鎖。在你的情況下,你實際上並不需要兩個選擇。

0

鎖只在提交或回滾時釋放。另一方面,單個事務本身不會阻塞。所以上面應該沒問題,只要只有一個線程正在做。

如果多於一個線程正在運行上面,我擔心你會死鎖。如果你想這樣做,你需要一個同時鎖定兩個集合的SQL語句,例如Jaydee的回答如上。