You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL事务执行LOCK TABLE时是否只能同时持有一个表锁?

测试现象背后的核心原因

你观察到的结果和InnoDB引擎层的锁逻辑无关,根源是你使用的LOCK TABLES是MySQL Server层提供的表锁命令,它本身的两个默认行为直接导致了该现象:

  • 执行LOCK TABLES语句时,会隐式提交当前会话的所有活跃事务,同时自动释放该会话之前通过LOCK TABLES持有的所有表锁,无法累计持有多批LOCK TABLES申请的锁
  • 只有单次LOCK TABLES同时指定多个表时,才会一次性持有多个表锁,例如LOCK TABLES test1 WRITE, test2 WRITE可以同时持有两个表的写锁

锁状态按执行顺序拆解

完全匹配你给出的测试步骤:

  1. 会话1执行begin开启事务后执行LOCK TABLE test1 write:首先隐式提交之前开启的空事务,释放会话1之前所有表锁(无),成功持有test1的写锁
  2. 会话2执行begin开启事务后执行LOCK TABLE test2 write:同样隐式提交空事务,成功持有test2的写锁
  3. 会话1执行LOCK TABLE test2 write:首先自动释放已经持有的test1写锁,再尝试申请test2的写锁,发现test2被会话2持有,进入阻塞
  4. 会话2执行LOCK TABLE test1 write:首先自动释放已经持有的test2写锁,尝试申请test1的写锁,此时test1的锁已经被会话1释放,直接加锁成功;同时test2的锁已经被会话2释放,会话1的阻塞直接解除,成功持有test2的写锁

额外补充说明

如果要测试InnoDB事务层面的锁特性,不要使用Server层的LOCK TABLES命令,应该使用InnoDB引擎层面的锁语法,比如SELECT * FROM test1 FOR UPDATE,这类锁支持同一个事务持有多个不同的表/行锁,不会出现执行新加锁语句就释放旧锁的情况。

内容的提问来源于stack exchange,提问作者Angle Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:15:01