MySql中的锁

锁的分类

根据锁的粒度,锁可以分为以下三大类:

  • 行级锁(InnoDB存储引擎)
  • 表级锁(MyISAM存储引擎)
  • 页级锁(BDB存储引擎)
  1. 行级锁
    行级锁是粒度最小的锁,它能锁定到具体某一行,加锁开销大,相应的支持并发也最高的。但可能会出现死锁的现象。它分为共享锁、排他锁等。
  2. 表级锁
    表级锁锁定的是这个表,一个用户对表进行写操作(插入、更新、删除等)要先获得写锁,进行读操作要先获取读锁。它的粒度相对行级锁而言是很大的。加锁消耗资源少,MyISAM和InnoDB都支持。它分为表共享(读)锁、表排他(独占写)锁。加锁消耗资源少,但访问冲突多,并发支持弱。
  3. 页级锁
    页级锁介于上述两者之间,它一次只锁定相邻的一组数据。也会出现死锁,并发一般。
读写锁

前面提到共享锁和排他锁两种模式,其实不管是在行级锁或者表级锁中,它们的含义是一样的。读的时候是共享,互不塞的;写的时候,会阻塞其他的写锁或者读锁访问资源,这都是为了保持数据安全。

意向锁

在InnoDB中还有两种意向锁。

  • 意向共享锁(IS),在对行数据进行加共享锁前,要先获取这张数据表的意向共享锁。
  • 意向排他锁(IX),同理,在对行数据进行加排他锁前,要先获取这张数据表的意向排他锁。
间隙锁

在InnoDB可重复读隔离级别下,会出现幻读的情况。间隙锁就是为了解决这个问题而引入的。所谓间隙,就是锁定行之外的表空间,比如一个表中有五行数据,执行select语句时,读锁定两行,那么其他三行都是在这两行外的间隙中。给间隙加锁,就可以保证表中的其他数据不会被修改。从而保证不会出现幻读的现象。
另外间隙锁都是左开右闭的原则对范围加锁的,注意是范围,而不是某一行。
由于间隙锁之间不是互斥的,所以可能会出现死锁的现象。
举一个例子

步骤A事务B事务
1select * from Tab where id = 5 for update;
2select * from Tab where id = 7 for update;
3insert into Tab value(1) 阻塞
4insert into Tab value(1) 阻塞

假设表Tab中已经有10条数据,分别是1-10,进行完步骤2之后,有三个间隙锁分别是,(1,5], (5,7], (7,10]。 间隙锁之间是不互斥的,那么
当A事务拿到(1,5], (5,7]并保持,去请求 (7,10];
这时B事务拿到(7,10]并保持,去请求(1,5], (5,7]。
就出现了死锁。

MySql中死锁的排查,可以通过show engine innodb status 命令查看死锁日志来分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值