也就是我们上面说到的在并发情况下会发生的这些问题,
如果并发操作不加控制,不加锁的话,就可能写入了不正确的数据 , 或者导致读取了不正确的数据,破坏了数据的一致性 。因此需要考虑加锁
InnoDB的七种锁共享/排他锁InnoDB呢实现了两种标准的行级锁:共享锁(简称S锁)、排他锁(简称X锁) 。
- 共享锁:简称为S锁,在事务要读取一条记录时,需要先获取该记录的S锁 。
- 排他锁:简称X锁 , 在事务需要改动一条记录时 , 需要先获取该记录的X锁 。
T1
持有行R的S
锁,那么另一个事务T2
请求访问这条记录时,会做如下处理:- T2 请求
S
锁立即被允许,结果T1和T2
都持有R行的S
锁 - T2 请求
X
锁不能被立即允许,此操作会阻塞
T1
持有行R的X
锁,那么T2
请求R的X、S
锁都不能被立即允许,T2
必须等待T1
释放X
锁才可以,因为X
锁与任何的锁都不兼容 。兼容性 SX S兼容不兼容 X 不兼容 不兼容意向锁意向锁是一种不与行级锁冲突的表级锁 。未来的某个时刻 , 事务可能要加共享或者排它锁时 , 先提前声明一个意向 。注意一下,意向锁,是一个表级别的锁 。
因为InnoDB是支持表锁和行锁共存的,如果一个事务A获取到某一行的排他锁,并未提交,这时候事务B请求获取同一个表的表共享锁 。因为共享锁和排他锁是互斥的,因此事务B想对这个表加共享锁时,需要保证没有其他事务持有这个表的表排他锁,同时还要保证没有其他事务持有表中任意一行的排他锁 。
然后问题来了,你要保证没有其他事务持有表中任意一行的排他锁的话 , 去遍历每一行?这样显然是一个效率很差的做法 。为了解决这个问题 , InnoDB提出了意向锁 。
如果一个事务A获取到某一行的排他锁 , 并未提交,这时候表上就有
意向排他锁
和这一行的排他锁
。这时候事务B想要获取这个表的共享锁 , 此时因为检测到事务A持有了表的意向排他锁
, 因此事务A必然持有某些行的排他锁 , 也就是说事务B对表的加锁请求需要阻塞等待 , 不再需要去检测表的每一行数据是否存在排他锁啦 。这样效率就高很多啦 。记录锁记录锁是最简单的行锁 , 仅仅锁住一行 。如:
SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE
,如果c1字段是主键或者是唯一索引的话,这个SQL会加一个记录锁(Record Lock)记录锁永远都是加在索引上的,即使一个表没有索引,InnoDB也会隐式的创建一个索引,并使用这个索引实施记录锁 。它会阻塞其他事务对这行记录的插入、更新、删除 。
一般我们看死锁日志时,都是找关键词,比如
lock_mode X locks rec but not gap
, 就表示一个X型的记录锁 。记录锁的关键词就是rec but not gap 。间隙锁为了解决幻读问题,InnoDB引入了间隙锁
(Gap Lock)
。间隙锁是一种加在两个索引之间的锁,或者加在第一个索引之前,或最后一个索引之后的间隙 。它锁住的是一个区间 , 而不仅仅是这个区间中的每一条数据 。比如
lock_mode X locks gap before rec
表示X型gap锁 。临键锁Next-key锁是记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁 。说得更具体一点就是:临键锁会封锁索引记录本身,以及索引记录之前的区间,即它的锁区间是前开后闭,比如
(5,10]
。如果一个会话占有了索引记录R的共享/排他锁,其他会话不能立刻在R之前的区间插入新的索引记录 。
插入意向锁插入意向锁,是插入一行记录操作之前设置的一种间隙锁 。这个锁释放了一种插入方式的信号 。它解决的问题是:多个事务,在同一个索引,同一个范围区间插入记录时,如果插入的位置不冲突,就不会阻塞彼此 。
假设有索引值4、7 , 几个不同的事务准备插入5、6,每个锁都在获得插入行的独占锁之前用插入意向锁各自锁住了4、7之间的间隙,但是不阻塞对方因为插入行不冲突
自增锁自增锁是一种特殊的表级别锁 。它是专门针对
AUTO_INCREMENT
类型的列,对于这种列,如果表中新增数据时就会去持有自增锁 。简言之,如果一个事务正在往表中插入记录,所有其他事务的插入必须等待,以便第一个事务插入的行,是连续的主键值 。
推荐阅读
- 引擎之旅 Chapter.4 日志系统
- 金文奎 金文奎
- 关于HM NISEDIT在新版系统下编译并运行提示权限不足问题的解决方案
- SR寄存器BP[x:0]位 痞子衡嵌入式:一个关于Segger J-Flash在Micron Flash固定区域下载校验失败的故事
- SQL的事务
- 面试突击87:说一下 Spring 事务传播机制?
- 一文搞定 Spring事务
- 魅族watch发布时间_魅族watch什么时候发布
- 关于男子登山遇地震:尿里加奶粉求生的信息
- r7 5800h和i7 11800h哪个好_r7 5800h和i7 11800h对比