两阶段锁协议

两阶段锁协议
 
在数据库系统领域,并发控制机制主要有两种,即锁和多版本机制。
 
1.事务在加锁时有多种方式:
 
一次性锁协议,事务开始时,即一次性申请全部的锁,以后不会再申请任何锁,若是其中某个锁不可用,则整个申请就不成功,事务就不会执行,在事务尾端,一次性释放全部的锁。一次性锁协议不会产生死锁的问题,但事务的并发度不高。
 
两阶段锁协议,整个事务分为两个阶段,前一个阶段为加锁,后一个阶段为解锁。在加锁阶段,事务只能加锁,也能够操做数据,但不能解锁,直到事务释放第一个锁,就进入解锁阶段,此过程当中事务只能解锁,也能够操做数据,不能再加锁。两阶段锁协议使得事务具备较高的并发度,由于解锁没必要发生在事务结尾。它的不足是没有解决死锁的问题,由于它在加锁阶段没有顺序要求。如两个事务分别申请了A, B锁,接着又申请对方的锁,此时进入死锁状态。
 
树形协议,假设数据项的集合知足一个偏序关系,访问数据项必须按此偏序关系的前后进行。如di->dj,则要想访问dj,必须先访问di。这种偏序关系导出一个有向无环图(DAG),所以称为树形协议。树形协议的规则有:
树形协议只有独占锁;
事务T第一次加锁能够对任何数据项进行;
此后,事务T对数据项Q的加锁前提是持有Q的父亲数据项的锁;
对数据项的解锁能够随时进行;
数据项被事务T加锁并解锁以后,就不能再被事务T加锁。
树形协议的优势是并发度好,由于能够较早地解锁。而且没有死锁,由于其加锁都是顺序进行的。
缺点是对不须要访问的数据进行没必要要的加锁。
 
时间戳排序协议,每一个事务都有一个惟一的时间戳,也就是其进入系统的时间。时间戳有大小之分,若是事务Ti比Tj先进入系统,则TS(Ti)<TS(Tj)。对于每一个数据项Q,有两个时间戳与其绑定:一个是W-TS(Q),表示最近一次写数据项Q的事务的时间戳;一个是R-TS(Q),表示最近一次读数据项Q的事务的时间戳。Thomas协议是对时间戳排序协议的改进,具体内容以下:
若事务Ti发起一个write(Q),则
若是TS(Ti)<R-TS(Q),则代表Ti准备写的值还没来得及写入,Q就提早被读取了,因此Ti的write(Q)操做被拒绝,而且事务Ti被回滚。
若是TS(Ti)<W-TS(Q),代表Ti写的值已过时,比它更新的值已经写到Q上,因此Ti的write(Q)操做被拒绝。
剩下的状况,write(Q)操做被容许。
 
事务在加锁时存在粒度的区别
如数据库锁,表锁,行锁,字段锁;页锁等。不一样的数据库支持的锁粒度不一样,BerkeleyDB支持页锁,即对数据项所在的内存页加锁。
 
 
2.多版本机制
锁是针对集中式数据管理设计的,缺点是下降了事务的并发,而且锁自己有开销。在分布式系统,尤为是读多写少的系统中,采用多版本机制更合适。每一个数据项都有多个副本,每一个副本都有一个时间戳,根据多版本并发控制协议(MVCC)维护各个版本。
 
MVCC又称为乐观锁,它在读取数据项时,不加锁;在更新数据项时,直到最后要提交时,才会加锁。这与CAS(Compare and Swap)的机制很相似,为了提升并发度,它更新数据前,会将数据拷贝一份,进行一系列修改,而且拷贝的同时,会记录当前的版本号(时间戳),当修改完毕,即将提交时,再检查此时的版本号是否与刚才记录的一致,若是不一致,则代表数据项被其余事务修改,当前事务的修改被取消。不然,正式提交修改,并增长版本号。
与MVCC相对,基于锁的并发控制机制称为悲观锁,由于它认为其余事务修改本身正在使用的数据项的几率很高,所以对数据项加锁以阻塞其余事务的读和写。
相关文章
相关标签/搜索