所在的位置: mysql >> mysql介绍 >> mysql的锁

mysql的锁

锁的分类

从性能上分为乐观锁(用版本对比来实现)和悲观锁

从对数据库操作的类型分,分为读锁和写锁(都属于悲观锁)。

读锁(共享锁,S锁(Shared)):针对同一份数据,多个读操作可以同时进行而不会互相影响

写锁(排它锁,X锁(eXclusive)):当前写操作没有完成前,它会阻断其他写锁和读锁

从对数据操作的粒度分,分为表锁和行锁

表锁与行锁表锁

每次操作锁住整张表。

开销小(不需要定位到某个元素,只需要定位到表),加锁快;

不会出现死锁;

锁定粒度大,发生锁冲突的概率最高,并发度最低;

一般用在整表数据迁移的场景。

表锁操作方式

手动增加表锁:locktable表名称read(write),表名称2read(write);

查看表上加过的锁showopentables;

删除表锁unlocktables;

行锁

每次操作锁住一行数据。

开销大,加锁慢;

会出现死锁;

锁定粒度最小,发生锁冲突的概率最低,并发度高。

InnoDB与MYISAM的最大不同点:InnoDB支持行级锁、支持事务

MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行update、insert、delete操作会自动给涉及的表加写锁。

InnoDB在执行查询语句SELECT时(非串行隔离级别),不会加锁。但是update、insert、delete操作会加行锁。

行锁操作方式

sql后增加forupdate来实现行锁。

forupdate在不走索引的时候会锁表!但是当要修改或者查询的数据不存在的时候,不会锁表,也不会锁定行!

读锁与写锁

读锁会阻塞写,但是不会阻塞读。而写锁则会把读和写都阻塞。

乐观锁与悲观锁乐观锁

乐观锁时会假设在极大多数情况下不会形成冲突,只有在数据提交的时候,才会对数据是否产生冲突进行检验。发生冲突后,不修改数据

实现方式

在数据库表中增加一列,记为version,当我们将数据读出时,将版本号一并读出,当数据进行更新时,会对这个版本号进行加1,当我们提交数据时,会判断数据库表中当前的version列值和当时读出的version是否相同,若相同说明没有进行更新的操作,不然,则取消这次的操作。

悲观锁

MySql的悲观锁就是打开事务,当启动事务时,如果事务中的sql语句涉及到索引并用索引进行了条件判断,那么会使用行级锁锁定所要修改的行,否则使用表锁锁住整张表。

实现方式

sql后增加forupdate来实现悲观锁。

forupdate在不走索引的时候会锁表!

当要修改或者查询的数据不存在的时候,不会锁表,也不会锁定行!

当InnoDB表有多个索引的时候,不同事务使用不同的索引去锁定同一条记录是怎么处理的

虽然用的不同辅助索引,但是相应的聚簇索引也会加锁,也就是主键会加锁,这样就防止并发修改了

间隙锁(GapLock)与临键锁(Next-keyLocks)间隙锁

间隙锁,锁的就是两个值之间的空隙。

间隙锁是在可重复读隔离级别下才会生效。

在普通索引列上,不管是何种查询,只要加锁,都会产生间隙锁,这跟唯一索引不一样;

在普通索引和唯一索引中,数据间隙的分析,数据行是优先根据普通索引排序,再根据唯一索引排序。

产生的条件

使用普通索引锁定;

使用多列唯一索引;

使用唯一索引锁定多行记录。

间隙锁开启状态处理:innodb_locks_unsafe_for_binlog

默认值为OFF,即启用间隙锁。

此参数是只读模式,如果想要禁用间隙锁,需要修改my.cnf(windows是my.ini)重新启动才行。

查看是否禁用:showvariableslike‘innodb_locks_unsafe_for_binlog’;

间隙锁的范围说明

唯一索引:id的间隙SELECT*FROMtableWHEREid3ANDid7FORUPDATE;产生的间隙为(1,10】

普通索引:name的间隙SELECT*FROMtableWHEREname=‘5’FORUPDATE;产生的间隙为(1,10】

临键锁(Next-keyLocks)

行锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间

这是Innodb在可重复读提交下为了解决幻读问题时引入的锁机制,

MySQL默认隔离级别是RR(可重复读),在这种级别下,如果你使用selectinsharemode或者selectforupdate语句,那么InnoDB会使用临键锁(记录锁+间隙锁),因而可以防止幻读;

即使你的隔离级别是RR(可重复读),如果你这是使用普通的select语句,那么此时InnoDB引擎将是使用快照读,而不会使用任何锁,因而还是无法防止幻读。




转载请注明:http://www.aierlanlan.com/rzfs/6009.html