【问题标题】:When I SELECT multiple rows FOR UPDATE, can I deadlock?当我选择多行进行更新时,我会死锁吗?
【发布时间】:2012-06-15 23:58:43
【问题描述】:

在 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 自动尝试按主键的顺序锁定行,但我想确定一下,并且我在文档中找不到正确的位置来告诉我到底发生了什么。

【问题讨论】:

    标签: mysql database-deadlocks


    【解决方案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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多