mysql中的锁

你说的曾经没有我的故事 提交于 2020-01-12 08:53:00

mysql中的锁

本文所讨论的是mysql8.0中的锁。

一、行锁-锁模式

共享锁S和排他锁X
InnoDB实现了两种行级锁,共享锁和排他锁。

共享锁:允许其他事务读取被锁住的行,但是不允许其他事务对被锁住的行进行写入操作。同时其他事务可以继续给该行加共享锁。
用法:select …for share

排他锁:防止其他事务读取或写入被该锁锁住的行,其他事务必须等待加锁事务的解锁之后才能操作,只有获取排他锁的事务可以读取数据或者写入数据。
用法:select …for update

二、表锁-意向锁

InnoDB支持多粒度的锁,为了实现多粒度锁,innodb采用了意向锁。意向锁是表级锁,表示稍后将对表中的某行加上共享锁或者排他锁。意向锁的主要目的就是表明某人正在某行加锁,或者将要在某行加锁。

IS:意向共享锁,指事务将在表中的单个行上加共享锁。
IX:意向排他锁,指事务将在表中的单个行上加排他锁。

例如, SELECT … FOR SHARE 语句设置一个IS,SELECT … FOR UPDATE 设置一个IX。

意向锁协议如下:
1、事务在获取表中某行上面的共享锁之前,必须获得IS锁,或者IX锁。
2、事务在获取表中某行上面的排他锁之前,必须获得IX锁。

各锁之间的关系如下:
在这里插入图片描述
意向排他锁会阻止其他事务对表加上X锁或S锁。意向共享锁会阻止其他的事务加上X锁。

三、锁类型

记录锁
记录锁锁住表中的一条索引记录。防止其他事务对该记录update等操作。

间隙锁
间隙锁是指加在索引记录之间的间隙上的锁。作用是防止对间隙锁范围内的数据进行插入操作。对于唯一索引的唯一行是不会加间隙锁的。此外,间隙锁可以由不同的事务加在同一个间隙上,例如可以由事务A在间隙上加了一个共享间隙锁,同时也可以由事务B在间隙上加一个独占间隙锁。间隙锁仅用于RR级别以上。用于防止幻读。

Next-Key 锁
next-key锁实际上是记录锁和间隙锁的组合。默认情况下,InnoDB的隔离级别是可重复读。在这种情况下,InnoDB使用next-key locks进行搜索和索引扫描,从而防止幻读。

四、两阶段锁协议-2PL

引入2PL是为了保证事务的隔离性,即多个事务在并发的情况下等同于串行的执行。 在数学上证明了如下的封锁定理:

如果事务是良构的且是两阶段的,那么任何一个合法的调度都是隔离的。

在一个事务里面,分为加锁(lock)阶段和解锁(unlock)阶段,也即所有的lock操作都在unlock操作之前,如下图所示:

在这里插入图片描述

因此在工程项目中,需要把最热点的记录,放到事务最后,这样可以显著的提高吞吐量。越热点记录离事务的终点越近(无论是commit还是rollback)。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!