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

MySQL单条语句是否原子执行?两连接按不同顺序锁表是否会引发死锁?

MySQL相关问题解答

问题1:MySQL是否会原子性地执行单条语句?

绝对会!MySQL对单条SQL语句的执行是保证原子性的——要么这条语句的所有操作全部完成,要么全部不执行,不会出现部分成功部分失败的情况。

举几个实际场景的例子:

  • 执行批量插入语句 INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob'),哪怕第二条数据存在主键重复的问题,整个INSERT操作都会失败,不会只插入第一条数据。
  • 执行更新语句 UPDATE accounts SET balance = balance - 100 WHERE id = 1,不管账户原本余额是否充足,要么余额成功扣减,要么因为约束限制等原因完全不执行,绝不会出现扣减一半的中间状态。

这里需要区分「单条语句的原子性」和「事务的原子性」:事务是把多条语句打包成一个原子执行单元,但单条语句本身,哪怕你没显式开启事务,MySQL也会保证它的原子性——哪怕是MyISAM这种不支持事务的存储引擎,单条语句的操作也是原子的,因为它会通过表锁来避免执行过程被打断。

问题2:两个连接按不同顺序锁表会导致死锁吗?

答案是不会。

这得从MySQL的LOCK TABLES机制说起:当你执行LOCK TABLES table1 WRITE, table2 WRITE这类多表锁语句时,MySQL并不是按照你写的顺序逐个获取锁的。它会先将你指定的所有表按字典序排序,然后按照这个统一的顺序来获取锁。

回到你的场景:

  • 连接1请求锁A和B,MySQL会先尝试获取A的写锁,再获取B的写锁;
  • 连接2请求锁B和A,MySQL同样会先尝试获取A的写锁,再获取B的写锁。

这样一来,两个连接都会先竞争A的锁:谁先拿到A的锁,就会继续去拿B的锁,拿到后完成锁表操作;另一个连接因为拿不到A的锁,会一直等待,直到前一个连接释放所有锁(执行UNLOCK TABLES或者断开连接)。

不会出现「连接1拿着A等B,连接2拿着B等A」的经典死锁场景,因为MySQL的锁表逻辑从根源上避免了这种循环等待的可能。

内容的提问来源于stack exchange,提问作者Rajat Aggarwal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 22:27:34