https://dev.mysql.com/doc/refman/8.0/en/innodb-deadlock-detection.html

如果Innodb_TABLE_LOCKS=1(缺省值),InnoDB就知道表锁 并且自动提交=0,并且它上面的MySQL层知道行级 锁上了.否则,InnoDB无法检测到a table lock set by a MySQL LOCK TABLES statement的死锁或存储引擎设置的锁 除InnoDB外,还参与了这笔交易.解决这些情况的方法是将 INNODB_LOCK_WAIT_TIMEOUT系统变量的值.

根据文档,我知道使用Innodb表和使用锁表如下will detect deadlocks:

SET autocommit=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;

这是正确的,还是我误解了?请纠正我

推荐答案

如果使用单个LOCK TABLES语句锁定事务期间要访问的所有表,则这些表将被原子锁定.没有陷入僵局的机会.

例如,在您的问题中包含的示例(手册中显示的示例)中,由于您锁定表t1t2,因此试图锁定这两个表之一的并发会话将被阻止.或者,如果并发会话首先锁定它们,则您的会话将被阻止both个表锁.等待的人不会锁定任何一个表,直到另一个表解锁.

如果会话一次锁定一个表,这不是原子的,如果它们累积锁,那么它们可能锁定一个表,然后被阻塞,等待另一个表上的锁.因此,这将是一个僵局.

事实上,它们不会使用连续的LOCK TABLES语句累积表锁.

https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html:

解锁表会显式释放当前会话持有的所有表锁.Lock Tables在获取新锁之前隐式释放当前会话持有的所有表锁.

因此不会发生死锁.如果您try 一个接一个地执行锁表,则实际上是让另一个会话获取您的会话持有的表锁.所以不会出现僵局.

Mysql相关问答推荐

mysql查询汇总数据

查找关联数据库表的超集

SQL中的搜索模式

MySQL没有使用S隐式附加到此二级索引的主键

可以在MySQL表名中使用表情包吗?

MySQL grant语句中的用户名区分大小写

java.lang.NullPointerException:无法调用com.proj.my.repository.OrderRepository.save(Object),因为this.orderRepository为空

MySQL 8.0.30 正则表达式词匹配特殊字符

MySQL IF() 函数根据指定条件执行代码块

MySQL 每组最大 n 只适用于多行

添加一个日期字段大于另一个日期字段的要求

估计行数 SQL

使用case查询并更新最后一条记录

MySQL中两个时间字段的分钟差

索引和多列主键

一次查询 MySQL 插入多行

在mysql中复制没有数据的数据库 struct (带有空表)

我可以在 PHP 中使用 PDO 创建数据库吗?

MySQL获取两个值之间的随机值

与 MySql 的连接正在自动中止.如何正确配置Connector/J?