1、数据准备
# age为普通索引
mysql> select * from user;
+
| id | username | age |
+
| 1 | 小a | 10 |
| 7 | 小b | 10 |
| 8 | 小c | 10 |
| 9 | 小d | 20 |
| 10 | 小e | 20 |
| 11 | 小f | 20 |
| 12 | 小g | 30 |
| 15 | 小h | 30 |
| 20 | 小i | 30 |
| 56 | 小j | 40 |
| 58 | 小k | 40 |
| 65 | 小l | 50 |
| 66 | 小m | 60 |
+
2、间隙锁导致死锁demo
【view1】
步骤一: 更新age=20的字段
set autocommit = 0;
START TRANSACTION;
UPDATE user SET age = 200 WHERE age = 20;
步骤三:新建age=30的数据,一直等待 view2 释放间隙锁
INSERT into `user` (username,age) VALUES("小壮",30);
【view2】
步骤二:更新age=30的字段
set autocommit = 0;
START TRANSACTION;
UPDATE user SET age = 300 WHERE age = 30;
步骤四:新建age=20的数据,需要 view1 释放间隙锁,这时发现死锁了, view2进行事物回滚,步骤三插入成功
INSERT into `user` (username,age) VALUES("小焦",20);
3、如何避免死锁
- 大事物变小事物
- 尽量通过唯一索引进行更新,防止大范围间隙锁产生;没有索引的话会锁全表