MYSQL 我说的那个锁,不是你的那个锁

一种数据库中有很多种锁,一般说起锁都是在提,是表锁,还是行锁,有没有死锁。但实际上就算是MYSQL 的锁的种类也不是那么简单。

实际上讨论一个锁,需要从以下几个方面来考虑

1  锁的种类   表锁  行锁

2  加锁的模式    

     LOCK_IS
     LOCK_IX
     LOCK_S
     LOCK_X
     LOCK_AUTO_INC

3  锁的类型     

4  锁的粒度

5  锁所处的隔离级别

NEXT KEY LOCK   
LOCK_GAP   
LOCK_REC_NOT_GAP   

LOCK_INSERT_INTENTION 

在知道这些东西后,才能更好的理解锁及其可能产生的各种死锁或锁超时的情况。

 

下面画了一个图,图中是MYSQL 中提供的锁的类型从图中可以看到 IS意向锁可以和除X锁的其他锁类型共存, X 锁则是和任何锁都是互斥的,和他本身也是一样,AI 锁 只和意向锁共存。

AUTO_INC 锁又叫自增锁(一般简写成 AI 锁),它是一种特殊类型的表锁,当插入的表中有自增列(AUTO_INCREMENT)的时候可能会遇到。当插入表中有自增列时,数据库需要自动生成自增值,在生成之前,它会先为该表加 AUTO_INC 表锁,其他事务的插入操作阻塞,这样保证生成的自增值肯定是唯一的。

  • AUTO_INC 锁互不兼容,同一张表一个时刻只能有一个自增锁

  • 自增锁不遵循二段锁协议,不是事务over时release,在 INSERT 语句执行完成时释放,用以提高并发插入的性能。

  • 自增值一旦分配了就会 +1,如果事务回滚,自增值也不会减回去,所以自增值可能会出现中断的情况。

而我们熟悉的行锁

LOCK_REC_NOT_GAP   ,record 锁本身是没有那么复杂的,他仅仅对他所在的记录进行一个锁,而相关的锁,仅仅是锁在索引上边的,如果是primary key 则直接锁在主键的位置,如果是二级索引,则除了锁在二级索引上,同时还需要锁在二级索引所指定的主键上。

NEXT KEY LOCK  next key lock,顾名思义  要不是  ( ]   [ )  ,(一个集合的概念),他主要的作用是防止幻读,也就是两次读不一致的情况,所以LOCK_GAP 主要是要看所处的

隔离级别是R R  ,  RC  那两种,MYSQL 默认的隔离级别是  RR ,但一般来说强烈建议 MYSQL 的通用的使用的隔离级别是  RC 。如果我们的隔离级别是RC 级别的情况下是不会有  next key lock 这样的锁。NEXT KEY LOCK 锁会将锁定记录周围的记录也进行一个锁定。

举例:如果我们的数据表中 的数据记录是   1   6  7 8 9  10 

select  * from t where number = 6 for update

此时锁定的记录

(1 6 7),此时如果在 1和 6之间插入数据会无法插入

GAP LOCK 间隙锁,间隙锁的知名度比 NEXT KEY LOCK 要大的的

(),标识间隙锁,间隙锁本来也可以理解成为范围锁,他将防止其他事务在这个范围内插入或修改记录,保证两次读取这个范围内的记录不会变,从而不会出现幻读现象。添加间隙锁和间隙锁之间是不冲突的,而添加间隙锁会严重影响数据库的并发性,还以上面的例子来说,他是要锁定 1(23456)7 ,同时不同的事务可以在间隙上持有冲突锁。例如,事务A可以在一个gap上持有一个共享的gap锁(gap S-lock),而事务B在同一个gap上持有一个独占的gap锁(gap X-lock)。允许存在冲突的间隙锁的原因是,如果从索引中清除一条记录,则必须合并不同事务在记录中持有的间隙锁。

LOCK_INSERT_INTENTION 插入意向锁,主要是服务于插入服务的,在数据库插入的时候会诊断插入数据的位置是否有间隙锁,也就是和间隙锁next key lock 这样的锁互斥。

记录锁和记录锁冲突,Next-key 锁和 Next-key 锁冲突,记录锁和 Next-key 锁冲突;

举例我们现在有下面一张表

我们模拟两个SESSION 

1  select * from insert_lock where id <= 5 for update

2  insert into insert_lock (id,name,employee_number) values (4,'rty',12)

上边的图中可以清晰的看到  select 的查询中包含了 GAP 锁,所以GAP 锁导致 插入失败。

那如何避免上面的情况 ,直接将数据库的隔离级别从  RR 改为 RC  这样的死锁就不会在存在了。

待......

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值