前言
MySQL数据库的InnoDB存储引擎是用于事务数据库,为了保证在不同的事务隔离级别(在后续章节中详细描述)中提交数据的安全性与正确性,其提供的锁类型包括共享锁(Shared Locks)、排他锁(Exclusive Locks)、意向锁(Intention Locks)、记录锁(Record Locks)、间隙锁(Gap Locks)、下一键锁(Next-Key Locks)、插入意向锁(Insert Intention Locks)、自动递增锁(AUTO-INC Locks)、断言锁(Predicate Locks)。
共享锁与排他锁
InnoDB存储引擎实现标准的行级锁,其中包括共享锁(s)与排他锁(x),其描述如下所示:
|
假设存在事务T1持有行记录r的共享锁(s),则其他事务T2对行记录r的锁请求的处理如下:
|
假设存在事务T1持有行记录r的排他锁(x),则其他事务T2对行记录r的任何锁的请求都不能被立刻授予,事务T2必须等待T1释放对行记录r的锁。
意向锁
InnoDB支持多颗粒度的锁操作,该操作允许行级锁与表级锁同时存在。例如,语句LOCK TABLES ... WRITE表示对指定的表执行x排他锁的操作。InnoDB使用意向锁实现多颗粒度级别的锁操作,意向锁是表级锁,其表示一个事务在稍后即将对表中的行记录执行排他锁或者共享锁的操作,意向锁包括两种类型如下所示:
|
例如,语句SELECT ... FOR SHARE表示设置IS,语句SELECT ... FOR UPDATE表示设置IX。
其中,意向锁的协议如下所示:
|
其中,表级锁的类型兼容性如下所示:
如上表所示,如果一个事务T请求的锁L1与一个已经存在的锁L2兼容,则锁L1被授予给事务T的锁请求,如果L1与L2冲突,则锁L1不能被授予给事务T的锁请求,在L1与L2发生冲突的情况下,L1必须等待L2释放锁,否则L1与L2将发生阻塞,即deadlock状态,其中L1、L2是指上表中的X、IX、S、IS的锁类型。
意向锁不阻塞任何请求,但全表的锁请求除外(例如,LOCK TABLES ... WRITE)。意向锁的主要目的是用于表明事务正在或者即将对表中的行记录设置锁。用户可以使用语句SHOW ENGINE INNODB STATUS查看表级锁的情况,如下所示:
由以上的分析可知,表级锁主要用在分布式系统中实现阻塞式而非抢夺式的同步机制。
记录锁
记录锁表示对一个索引记录的锁,例如,语句SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;能阻止任何其他事务执行c1=10的增加、删除、更新操作。记录锁始终执行对索引行的锁操作,即使该表没有定义索引,在表没有定义索引的情况下,InnoDB将创建一个隐藏的主级索引并使用该索引执行记录的锁操作。
使用语句SHOW ENGINE INNODB STATUS,查看记录锁的情况,如下所示:
(未完待续)