MySql锁机制:共享锁、排它锁;行锁、表锁、页锁;

共享锁

# 查询语句后添加 lock in share mode 即可添加共享锁 注意:需要先开启事务。
begin;/begin work;/start transaction; (三者选一就可以)
select * from t_user where age = 20 lock in share mode;
commit;/commit work;

对年龄为20岁的用户添加共享锁,使得这些用户在当前事务提交前不会被其他事务修改。但是其他事务仍然可以读取该部分数据,也可以对该部分数据添加共享锁。
当事务同时增加共享锁时候,事务的更新必须等待先执行的事务 commit 后才行,如果同时并发太大可能很容易造成死锁。

排它锁

start transaction;
select * from t_user where age = 20 for update;

排它锁只允许当前事务对锁定的数据进行修改,其他事务无法修改,只能读取,也无法添加共享锁。

表锁

表级锁是mysql锁中粒度最大的一种锁,表示当前的操作对整张表加锁,资源开销比行锁少,不会出现死锁的情况,但是发生锁冲突的概率很大。被大部分的mysql引擎支持,MyISAM和InnoDB都支持表级锁,但是InnoDB默认的是行级锁。

页锁

页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁,使用较少。

行锁

行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。有可能会出现死锁的情况。 行级锁按照使用方式分为共享锁和排他锁。

InnoDB行锁

在不通过索引条件查询的时候,InnoDB使用的确实是表锁。
由于 MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行 的记录,但是如果是使用相同的索引键,是会出现锁冲突的。
当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论 是使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁。
即便在条件中使用了索引字段,但是否使用索引来检索数据是由 MySQL 通过判断不同 执行计划的代价来决定的,如果 MySQL 认为全表扫 效率更高,比如对一些很小的表,它 就不会使用索引,这种情况下 InnoDB 将使用表锁,而不是行锁。因此,在分析锁冲突时, 别忘了检查 SQL 的执行计划(explain查看),以确认是否真正使用了索引。

意向锁

InnoDB 支持多种粒度的锁,也就是行锁和表锁。为了支持多粒度锁定,InnoDB 存储引擎引入了意向锁(Intention Lock)。那什么是意向锁呢?我们在这里可以举一个例子:如果没有意向锁,当已经有人使用行锁对表中的某一行进行修改时,如果另外一个请求要对全表进行修改,那么就需要对所有的行是否被锁定进行扫描,在这种情况下,效率是非常低的;不过,在引入意向锁之后,当有人使用行锁对表中的某一行进行修改之前,会先为表添加意向互斥锁(IX),再为行记录添加互斥锁(X),在这时如果有人尝试对全表进行修改就不需要判断表中的每一行数据是否被加锁了,只需要通过等待意向互斥锁被释放就可以了。意向锁分为两种。

意向共享锁(IS)

事务想要在获得表中某些记录的共享锁,需要在表上先加意向共享锁。

意向互斥锁(IX)

事务想要在获得表中某些记录的互斥锁,需要在表上先加意向互斥锁。

随着意向锁的加入,锁类型之间的兼容矩阵也变得愈加复杂。意向锁其实不会阻塞全表扫描之外的任何请求,它们的主要目的是为了表示是否有人请求锁定表中的某一行数据。

行锁的算法

InnoDB存储引擎有3种行锁的算法。

Record Lock

单个行记录上的锁。Record Lock总是会去锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这时InnoDB存储引擎会使用隐式的主键来进行锁定。
​单条索引上加锁,record lock 永远锁的是索引,而非数据本身,如果innodb表中没有索引,那么会自动创建一个隐藏的聚集索引,锁住的就是这个聚集索引。所以说当一条sql没有走任何索引时,那么将会在每一条聚集索引后面加X锁,这个类似于表锁,但原理上和表锁应该是完全不同的。

Gap Lock

间隙锁,锁定一个范围,但不包含记录本身。是在索引的间隙之间加上锁。

Next-Key Lock

Gap Lock + Record Lock,锁定一个范围,并且锁定记录本身。
Next-Key Lock是结合了Gap Lock和Record Lock的一种锁定算法,在Next-Key Lock算法下,InnoDB对于行的查询都是采用这种锁定算法。
除了Next-Key Locking,还有Previous-Key Locking技术。但是不是所有索引都会加上Next-key Lock的,在查询的列是唯一索引(包含主键索引)的情况下,Next-key Lock会降级为Record Lock。

脏读

读未提交。事务A读取了事务B更新的数据,然后事务B回滚了,那么事务A读取的数据是脏数据,因为事务A读取了事务B未提交的数据。

不可重复读

事务A多次读取同一个数据,但是事务B在事务A的读取间隙更新并提交了数据,导致事务A读取结果不一致。

幻读

关于幻读请参考下一篇博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值