锁表会导致InnoDB死锁吗?

时间:2018-11-26 14:56:48

标签: php mysql innodb database-deadlocks

从MySQL手册(https://dev.mysql.com/doc/refman/8.0/en/innodb-deadlocks.html):

  

为减少死锁的可能性,请使用事务而不是LOCK TABLES语句

在InnoDB中使用LOCK TABLES怎么可能导致死锁?

例如,如果我写

SET autocommit=0;
LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE;
... do something with tables t1-t4 here ...
COMMIT;
UNLOCK TABLES;

我每次执行此脚本时是否真的需要检查1213之类的错误?

1 个答案:

答案 0 :(得分:1)

如果确保在一个LOCK TABLES语句中锁定要读取或写入的表 all ,则应该可以避免死锁。

但是,如果您的代码引用了除锁定表之外的其他任何表,那么就有死锁的风险。

如果可以使用事务代替,则避免使用LOCK TABLES的另一个很好的理由是允许行级锁定。 LOCK TABLES仅在表级别锁定,这意味着并发会话无法触摸表中的任何行,即使您的会话不需要锁定它们也是如此。

对于需要允许多个会话并发访问表的软件来说,这是一个缺点。您正在强制执行表级锁定,这将限制软件的吞吐量,因为所有访问表的会话将相互排队,并被迫串行执行。

  

“使用t2”是什么意思?读锁?如果我只使用示例中的WRITE锁,该怎么办?

我认为他的意思是如果您从表t2中读取。由于您已将该表锁定为WRITE,因此还包括阻止该表的所有读取器。除非您解锁,否则其他会话都无法读取或写入表。

  

我不关心性能。在这种情况下,我想使事情变得尽可能简单,并且与使用带有偏执级别错误检查的事务相比,LOCK TABLES对我来说更加直观。

您最终会找到一种情况,希望您的软件具有良好的性能。您必须更加习惯使用交易。