层次锁
层次锁,更多地是在数据库设计中被提到,但也有少数分布式锁系统也实现这个概念。下面内容主要还是从数据库设计的角度来理解层次锁的概念。 1. 事务锁粗略说来,当执行SQL语句时数据库都会开启事务,在SQL执行完毕commit时,会把所有受影响数据写到磁盘文件并结束事务。在事务执行期间,为了保证事务的ACID,SQL所影响到的表、行等数据都会被不同程度的进行锁定,我们笼统称为“事务锁”。从使用者的角度来看,一般数据库都提供了表锁和行锁,其中行锁要比表锁粒度要细很多,被认为是支持高并发事务的关键。 但仅靠表锁和行锁是不够的,比如一个事务进行了行锁定,而另一个事务需要表锁定,那如何判断表锁定是否可以成功?同样,一个事务锁定了某些行,而另一事务需要读取这些行,是否允许读取?当考虑到不同的数据库操作和隔离级别时,锁的实现会变得非常复杂。 2. 锁的类型有一个关键问题是,数据库锁用来锁什么,从数据库实现上来说是锁数据库内部的数据库结构,因为各数据库实现不一,因此锁的内容也就有所区别。对Oracle来说存在表、行、回滚段、Redolog等结构;SQLServer存在表、页、行等结构,这些结构在逻辑上存在上下级关系,比如SQLServer中,每个表的数据有多个页构成,而页中有包含了多行的内容,而一般认为行没有下级数据结构,为事务操作的最小单位。既可以对表,也可以对页、行对象加锁,抽象一点,称这些能加锁的对象为Node。 数据库中存在下面类型的锁:
上面三种锁是描述了某个Node被修改时的锁类型,但因为Node存在上下级关系,但Node被加锁时,我们需要评估上级Node的加锁情况,比如当给行加各种锁的时候,表的加锁情况是神马? 之所以这样做的原因是因为存在一个需求:
这样事务A在更新数据之前会对表加意向排他锁,而事务B在加排他锁之前发现A加的意向排他锁,所以必须等待A完成,从而避免了逐行检查的问题。 从下层节点来说,意向锁是对所有下级Node加锁情况的整体说明;但从上层Node来说,意向锁描述的是其下层Node正在被加某种锁(比如排他锁),或说下层Node有加某种锁的意向,这样正是“意向"一词的由来。 意向锁与共享锁、排他锁、共享锁不同的时,只能加在存在下级Node的Node对象上,比如可以加在表、页上,但不能加在行上,因为行是事务加锁的基本元,不存在有”意向“的下级Node。 意向锁具体有分:意向共享锁(Intent Share)、意向排他锁(Intent Exclusive)、共享意向排他锁(Share Intent Exclusive),下面逐一说明
3. 相容矩阵因为对同一Node可能存在多个事务期望对该Node加不同的锁,这就需要列出锁直接的相容性,只有相容的锁才允许被同时加在同一Node上,否则后面事务就需要等待。 下表直接引用自微软网站:http://msdn.microsoft.com/en-us/library/aa213041(v=sql.80).aspx
| ? | Existing granted mode | Requested mode | IS | S | U | IX | SIX | X | Intent shared (IS) Yes Yes Yes Yes Yes No Shared (S) Yes Yes Yes No No No Update (U) Yes Yes No No No No Intent exclusive (IX) Yes No No Yes No No Shared with intent exclusive (SIX) Yes No No No No No Exclusive (X) No No No No No No
---|