什么是锁

锁是数据库系统区别于文件系统的一个关键特性
**
锁机制用于管理对共享资源的并发访问,Innodb存储引擎会在行级别上对表数据上锁,不过Innodb存储引擎也会在数据库内部其他多个地方使用锁,从而允许对多种不同资源提供并发访问。例如,操作缓冲池中的LRU列表,删除、添加、移动LRU列表中的元素,为了保证一致性,必须有锁的介入。数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性。

对于MyISAM引擎,其锁是表锁设计。
并发读没有问题,但是并发插入时的性能就要差一些,若插入是在“底部”, MYISAM存储引擎还是可以有一定的并发写入操作。
对于 Microsoft SQL Server数据库,在 Microsoft SQL Server2005版本之前其都是页锁的,相对表锁的 Myisam引擎来说,并发性能有所提高。页锁容易实现,然而对于热点数据页的并发问题依然无能为力。到2005版本, Microsoft SQL Server开始支持乐观并发和悲观并发,在乐观并发下开始支持行级锁。锁越多开销就越大,因此它会有锁升级。在这种情况下,行锁会升级到表锁,这时并发的性能又回到了以前。
Innodb存储引擎锁的实现和 Oracle数据库非常类似,提供一致性的非锁定读、行级锁支持。行级锁没有相关额外的开销,并可以同时得到并发性和一致性

一、行锁与表锁的区别

锁定力度: 表锁>行锁
加锁效率: 表锁> 行锁
冲突概率: 表锁> 行锁
并发性能: 表锁<行锁

二、行锁:共享锁(Shared Locks)

共享锁,又称为读锁,简称S锁。
共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改;

加锁:

select * from student where id =1 LOCK IN SHARE MODE:

释放锁:事务结束

三、行锁:排他锁(Exclusion Locks)

排他锁又称为写锁,简称X锁。

排他锁不能与其他锁并存,如一个事务获取了一个数据行的排它锁,其他事务就不能再
获取该行的锁(共享锁、排他锁),只有该获取了排他锁的事务是可以对数据进行修改和读取。

加锁:
自动:delete/update/insert 默认加上X锁;
手动:select * from student where id =1 FOR UPDATE;
释放锁: 事务结束。

四、锁的作用

行锁到底锁住了什么?
是一行数据(Row)吗?
是一个字段(Column)吗?

建立表

t1,没有索引
image.png

在第一个事务里面将第一行数据进行锁住
image.png

image.png
发现id =3 的时候没有执行成功,整张表给锁住了。

image.png
新建一张表 是有主键id的
image.png
image.png
在一个表里面进行查询
image.png
发现不行,
image.png
当我尝试id=4的时候,发现是可以的。
为什么加了主键的和不加主键的不一样。

image.png
然后我们创建一个唯一的索引
image.png
尝试锁一下这个字段
image.png
发现也不能成功
锁住的是行锁

InnoDB到底锁的是什么?
image.png
可以看出锁的是索引。

1、为什么一张表没有索引,加行锁会锁住整张表?
一张表有没有可能没有索引?
不可能,有聚集索引

没有命中索引 -> 全表扫描->把所有的隐藏的聚集索引全部锁住

image.png

如果锁住二级索引,它会把它的聚集索引也会锁住。

五、行锁的算法:锁住了什么范围?

image.png
image.png

记录有N个,那么间隙就有N+1个

记录锁(Record Lock):锁定记录

image.png

间隙锁(Gap Lock):锁定范围

image.png
s数据
1 4 7 10

image.png

https://www.jianshu.com/p/32904ee07e56

临建锁(Next-key Lock) :锁定范围加记录

image.png

默认使用临建锁,没有任何一个索引记录会退化成间隙锁,如果查询条件为精确的话,会退化成记录索锁