温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

什么操作引发数据库Deadlock死锁

发布时间:2026-10-09 04:03:55 来源:亿速云 阅读:106 作者:小樊 栏目:数据库

数据库死锁(Deadlock)是指两个或多个事务在执行过程中,因互相持有对方需要的锁而互相等待,导致都无法继续前进的情况。

下面从常见操作 / 场景来说明什么操作容易引发死锁。


一、最典型的引发死锁的操作

1️⃣ 交叉更新不同表 / 不同行(顺序不一致)

最常见死锁原因

事务A:
UPDATE table1 SET ... WHERE id = 1;
UPDATE table2 SET ... WHERE id = 2;

事务B:
UPDATE table2 SET ... WHERE id = 2;
UPDATE table1 SET ... WHERE id = 1;
  • 事务A锁住 table1
  • 事务B锁住 table2
  • 互相等待对方释放 → 死锁

✅ 本质:加锁顺序不一致


2️⃣ 更新同一张表,但行锁顺序不同

事务A:
UPDATE user SET money = money - 10 WHERE id = 1;
UPDATE user SET money = money + 10 WHERE id = 2;

事务B:
UPDATE user SET money = money - 10 WHERE id = 2;
UPDATE user SET money = money + 10 WHERE id = 1;

即使是一张表,也会死锁。


3️⃣ 先 SELECT … FOR UPDATE,再 UPDATE

-- 事务A
SELECT * FROM order WHERE id = 1 FOR UPDATE;
UPDATE order SET status = 2 WHERE id = 2;

-- 事务B
SELECT * FROM order WHERE id = 2 FOR UPDATE;
UPDATE order SET status = 2 WHERE id = 1;

FOR UPDATE 会加行锁,顺序反了就死锁。


4️⃣ 范围更新 / 间隙锁(MySQL InnoDB 常见)

-- 事务A
UPDATE user SET age = 18 WHERE id BETWEEN 1 AND 10;

-- 事务B
INSERT INTO user(id, name) VALUES (5, 'Tom');
  • A 加间隙锁
  • B 插入被阻塞
  • 若反过来也可能死锁

5️⃣ 外键更新引发隐式锁

更新主表 → 子表自动加锁
另一个事务反向更新 → 死锁

外键检查会隐式加锁,容易被忽略。


6️⃣ 长事务 + 高并发

  • 事务长时间不提交
  • 锁一直不释放
  • 并发一高,死锁概率飙升

二、常见死锁场景总结

场景 是否常见
更新顺序不一致 ✅ 最常见
并发修改多行 ✅
显式 FOR UPDATE ✅
间隙锁 / 范围锁 ✅(MySQL)
外键级联 ⚠️
单条 UPDATE ❌ 几乎不会

三、如何避免死锁(关键)

✅ 1. 统一加锁顺序

永远先锁 id=1,再锁 id=2

✅ 2. 缩小事务范围

  • 不要在大事务里做 IO / RPC

✅ 3. 避免 SELECT FOR UPDATE 滥用

✅ 4. 使用索引,避免表锁

✅ 5. 设置死锁重试机制

捕获 Deadlock 异常 → 重试事务

四、一句话总结

死锁不是“某个操作”的问题,而是“多个事务以不同顺序抢同一批锁”的问题。

如果你愿意,我可以:

  • 用 MySQL / Oracle / PostgreSQL 具体举例
  • 帮你分析一段真实 SQL 是否可能死锁
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手