假设有表数据如下:
mysql> select * from t20;
+-----+------------+------+
| uid | login_name | age |
+-----+------------+------+
| 5 | neco | 18 |
| 7 | tom | 20 |
| 8 | peter | 20 |
| 9 | jack | 20 |
+-----+------------+------+
此时事务A执行以下内容:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update t20 set age=20 where age >= 18;
Query OK, 1 row affected (0.00 sec)
Rows matched: 4 Changed: 1 Warnings: 0
此时因为事务尚未提交,所以锁一直都是事务A持有的。
然后事务B执行如下内容:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update t20 set age=20 where age >= 18;
因为此时锁被事务A持有,无法获取到锁,只能等待,即此时只是获取到了间隙锁
如果此时事务A再执行插入操作:
mysql> insert into t20 values(4, 'yy', 27);
Query OK, 1 row affected (0.00 sec)
此时事务A尝试获取插入意向锁,但是却被告知需要等待事务B完成后才能拿到,那么事务A和事务B就相互等待,于是就形成了死锁。
mysql> update t20 set age=20 where age >= 18;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
但是并不是说,所有的插入都不行,如果将上面的插入语句改变成
insert into t20 values(20, 'yy', 27);
此时因为此条记录的id不在事务B的间隙锁的锁住的范围内,是可以插入的,不会形成死锁。
如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~
网友评论