【MySQL】锁

锁是因为多个线程争抢资源而出现的机制,锁的出现可以保证在并发访问数据时数据的一致性和有效性,其重要性不言而喻
MySQL中的锁按照粒度分为全局锁,表级锁和行级锁,MySQL的锁机制最显著的特点是不同的存储引擎支持不同的锁机制

1.全局锁

全局锁就是对整个数据库实例进行加锁,加锁后实例处于只读状态只能够进行读取操作,其它的操作都将会被阻塞

加锁:
  flush tables with read lock;
解锁:
  unlock tables;

2.表级锁

表级锁就是锁住整张数据表,表级锁主要分为三类:表锁,元数据锁和意向锁

2.1 表锁

表锁可以分为表共享读锁(read lock)和表独占写锁(write lock),通常我们简称为读锁和写锁

加锁:
  lock tables 表名......read/write;
解锁:
  unlock tables;

读锁的特点是只允许读取数据的操作,其它操作会被阻塞
写锁是只允许当前客户端进行读取和修改操作,其它客户端的操作会处于阻塞状态

2.2 元数据锁

元数据锁的加锁过程是由系统自动控制的,不需要我们自己手动进行加锁,元数据锁会在访问数据表的时候自动加上,元数据可以理解为表结构
元数据锁的作用是当有事务未提交的时候防止事务对表结构进行修改,避免DML和DDL语句冲突
元数据锁同样也有读锁和写锁,当对一张表进行增删改查的操作的时候会加读锁,对表结构进行修改的时候加写锁

2.3 意向锁

在执行DML语句的时候会加表锁和行锁,为了避免这两个锁冲突所以引入了意向锁
表锁在加锁之前首先要对数据的每一行进行检查,确定数据没有加行锁之后再进行加锁,意向锁则可以减少表锁的检查
意向锁分意向共享锁(IS)和意向排他锁(IX)

IS和表锁的读锁兼容,和写锁排斥
IX则是和表锁的读锁写锁都排斥,但意向锁之间是兼容的

当表锁和意向锁排斥,说明此时表锁就不能进行加锁
意向锁是存储引擎自动维护的,不需要手动添加

3.行级锁

行级锁每次加锁锁住的是数据表的一行数据,发生锁冲突的概率最低,用于InnoDB引擎
由于InnoDB的数据是基于索引组织的,所以行锁是对索引上的索引项进行加锁
行级锁分为三种:行锁,间隙锁和临建锁

3.1 行锁

锁定单个行记录的锁,在MySQL中锁定粒度最细,但因为粒度小所以开销也大,而且容易死锁,InnoDB实现了两种类型的行锁:共享锁(S)和排他锁(X)

  • 共享锁:多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改
  • 排他锁:不能与其他锁并存,如果一个事务获取了一个数据行的排他锁,那么其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,获取排他锁的事务可以对数据进行读取和修改

由此可以得出的结论是共享锁和共享锁兼容,排他锁和其它锁都是互斥的

一般执行insert,update,delete语句的时候InnoDB引擎会自动加上排他锁
如果在select语句后面手动加上lock in share mode 就是加共享锁,select语句后面加for update就是加排他锁

由于InnoDB的行锁是对索引进行加锁,如果不通过索引来检索数据的话,InnoDB将会对数据表中所有的数据进行加锁,此时行锁就会升级为表锁

3.2 间隙锁和临建锁

间隙锁:锁住索引记录间隙,防止其他事务在这个间隙进行insert操作产生幻读,间隙锁之间可以共存
临建锁:行锁和间隙锁的组合
MySQL默认事务隔离级别为可重复读(repeatable read),InnoDB在这种隔离级别下运行会使用临建锁来防止幻读
之所以将二者放在一起,是因为InnoDB引擎中在某些情况下二者能进行转换

  • 使用唯一索引进行等值查询(类似where id=3这种),给不存在的记录加锁时为间隙锁
  • 使用普通索引进行等值查询,如果遍历到最后一个值不满足查询要求,临建锁退化为间隙锁
  • 使用唯一索引进行范围查询,加临建锁

4.死锁

在MyISAM中不会产生死锁,但是在InnoDB中则会有发生死锁的可能,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待,而在InnoDB中,锁是逐步获得的

由于在InnoDB中行级锁是锁索引,而索引分为主键索引和非主键索引两种,所以如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引,当这两条语句同时执行的时候就会发生死锁

想要避免死锁发生,常见的方式有下面几种:

  1. 如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表
  2. 在同一个事务中,尽可能做到一次锁定所需要的所有资源
  3. 尝试将行级锁升级为表级锁来减少死锁发生的概率

关于MySQL锁的内容到这结束,完

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星鸦wyk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值