2012-06-13 34 views
3

在MySQL + InnoDB中,假設我有一個表以及兩個既執行「SELECT ... FOR UPDATE」的線程。假設兩個SELECT語句最終選擇多行,例如,他們最終都選擇了行R42和R99。這有可能會陷入僵局嗎?當我選擇多行FOR UPDATE時,我可以死鎖嗎?

我在想這種情況:第一個線程試圖鎖定R42,然後R99,第二個線程試圖鎖定R99,然後R42。如果我不走運,這兩個線程將陷入僵局。

我在MySQL Glossary for "deadlock"讀取

當交易鎖定在多個表中的行(通過語句,如UPDATE或SELECT ... FOR UPDATE),就可能出現死鎖,但以相反的順序。 ...

爲了減少死鎖的可能性,...在SELECT ... FOR UPDATE和UPDATE ... WHERE語句中使用的列上創建索引。

提示,在我的情況(單表)我不會僵局,也許因爲MySQL會自動嘗試在主鍵的順序來鎖定行,但我想肯定,我可以在文檔中找不到適當的地方,告訴我到底發生了什麼。

回答

2

從MySQL文檔

InnoDB uses automatic row-level locking. You can get deadlocks even in the case of 
transactions that just insert or delete a single row. That is because these operations  
are not really 「atomic」; they automatically set locks on the (possibly several) index 
records of the row inserted or deleted. 

http://dev.mysql.com/doc/refman/5.1/en/innodb-deadlocks.html

所以通常,死鎖是不是致命的,你只需要再次嘗試,或添加適當的索引,使更少的行掃描,因此較少的行是鎖定。