精通MySQL之锁篇 (3)

id、number为边缘数据

非唯一索引等值

update news set number=3 where number=4;

检索条件number=4,向左取得最靠近的值2作为左区间,向右取得最靠近的5作为右区间,因此,session 1的间隙锁的范围(2,4),(4,5),即记录(id=1,number=2)和记录(id=3,number=4)之间间隙会被锁定,记录(id=3,number=4)和记录(id=6,number=5)之间间隙被锁定。

当我们添加数据时,结果如下:

insert into news value(2,3);
均在间隙内,阻塞
insert into news value(7,8);
均在间隙外,成功
insert into news value(2,8);
id在间隙内,number在间隙外,成功
insert into news value(4,8);
id在间隙内,number在间隙外,成功
insert into news value(7,3);
id在间隙外,number在间隙内,阻塞
insert into news value(7,2);
id在间隙外,number为上边缘数据,阻塞
insert into news value(2,2);
id在间隙内,number为上边缘数据,阻塞
insert into news value(7,5);
id在间隙外,number为下边缘数据,成功
insert into news value(4,5);
id在间隙内,number为下边缘数据,阻塞

我们可以得到只要number(where后面的)在间隙里(2 3 4),不包含最后一个数(5)则不管id是多少都会阻塞。 如果是下边缘数据需要看id是否在间隙内。

主键索引范围

由于主键不能重复,所以id无边缘数据。

update news set number=3 where id>1 and id <6;
insert into news value(2,3);
均在间隙内,阻塞
insert into news value(7,8);
均在间隙外,成功
insert into news value(2,8);
id在间隙内,number在间隙外,阻塞
insert into news value(4,8);
id在间隙内,number在间隙外,阻塞
insert into news value(7,3);
id在间隙外,number在间隙内,成功

我们可以得到只要id(在where后面的)在间隙里(2 4 5),则不管number是多少都会阻塞。

非唯一索引无穷大

update news set number=3 where number=13 ;
insert into news value(11,5);
执行成功
insert into news value(12,11);
执行成功
insert into news value(14,11);
阻塞
insert into news value(15,12);
阻塞

检索条件number=13,向左取得最靠近的值11作为左区间,向右由于没有记录因此取得无穷大作为右区间,因此,session 1的间隙锁的范围(11,无穷大),当id和number同时满足 ,才会阻塞。

死锁

两个 session 互相等等待对方的资源释放之后,才能释放自己的资源,造成了死锁,主要是顺序出现问题。

我们session1先给id=1加锁,session2再给id=2加锁,此时session1想再给id=2加锁,但session2已经给它加锁了,就会造成死锁。

如何解决死锁?

MySQL默认会主动探知死锁,并回滚某一个影响最小的事务,等待另一个事务执行完成之后,再重新执行该事务。

总结

本文作为大数据开发指南MySQL的第三篇详细介绍了MySQL锁的内容,希望大家能够跟着老刘的文章,好好捋捋思路,争取能够用自己的话把这些知识点讲述出来!

尽管当前水平可能不及各位大佬,但老刘会努力变得更加优秀,让各位小伙伴自学从此不求人!

大数据开发指南地址如下:

github:https://github.com/BigDataLaoLiu/BigDataGuide

码云:https://gitee.com/BigDataLiu/BigDataGuide

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdgxy.html