当我选择多行FOR UPDATE时,我可以死锁吗?

时间:2012-06-13 03:40:13

标签: mysql database-deadlocks

在MySQL + InnoDB中,假设我有一个表,两个线程都执行“SELECT ... FOR UPDATE”。假设两个SELECT语句最终选择多行,例如它们最终都选择了行R42和R99。这可能会陷入僵局吗?

我正在考虑这种情况:第一个线程试图锁定R42然后R99,第二个线程试图锁定R99然后锁定R42。如果我运气不好,两个线程就会陷入僵局。

我在MySQL Glossary for "deadlock"中读到了

  

当事务锁定多个表中的行(通过诸如UPDATE或SELECT ... FOR UPDATE之类的语句)但是以相反的顺序锁定时,可能会发生死锁。 ...

     

为了减少死锁的可能性,...在SELECT ... FOR UPDATE和UPDATE ... WHERE语句中使用的列上创建索引。

这个暗示在我的情况下(单个表)我不会死锁,也许是因为MySQL会自动尝试按主键的顺序锁定行,但我想确定,并且我无法在文档中找到正确的位置,告诉我到底发生了什么。

1 个答案:

答案 0 :(得分:1)

来自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

所以一般来说,死锁并不是致命的,你只需要再试一次,或者添加适当的索引以便扫描更少的行,从而锁定更少的行。