MYSQL关于锁的类型和模式的讨论
本篇内容介绍了"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 锁导致 插入失败。
"MYSQL关于锁的类型和模式的讨论"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!