分享

数据库并发控制技术(3)

 sunshineapril 2010-11-24
在2级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读。
3级封锁协议 3级封锁协议的内容是:1级封锁协议加上事务T在读取数据之前必须先对其加S锁,直到事务结束才释放。 3级封锁协议除防止丢失或覆盖更新和不脏读数据外,还进一步防止了不可重复读和幻想读。例如下图,使用3级封锁协议解决了不可重复读和幻像读问题。
上图中,事务1在读A,B之前,先对A,B加S锁,这样其他事务只能再对A,B加S锁,而不能加X锁,即其他事务只 能读A,B,而不能修改它们。所以当事务2为修改B而申请对B的X锁时被拒绝,使其他无法执行修改操作,只能等待事务1释放B上的锁。接着事务1为验算再 读A,B,这时读出的B仍是100,求和结果仍为150,即可重复读。 上述三级协议的主要区别在于什么操作需要申请封锁以及何时释放锁(即持锁时间)。三级封锁协议可以总结为下表。
(6)保证并行调度可串行性的封锁协议――两段封锁协议 可串行性是并行调度正确性的唯一准则,两段锁(two-phase locking,简称2PL)协议是为保证并行调度可串行性而提供的封锁协议。 两段封锁协议规定: ①在对任何数据进行读、写操作之前,事务首先要获得对该数据的封锁,而且②在释放一个封锁之后,事务不再获得任何其他封锁。 所谓“两段”锁的含义是,事务分为两个阶段,第一阶段是获得封锁,也称为扩展阶段,第二阶段是释放封锁,也称为收缩阶段。 例如,事务1的封锁序列是: Slock A... Slock B… Xlock C… Unlock B… Unlock A… Unlock C; 事务2的封锁序列是: Slock A... Unlock A… Slock B… Xlock C… Unlock C… Unlock B; 则事务1遵守两段封锁协议,而事务2不遵守两段封锁协议。 可以证明,若并行执行的所有事务均遵守两段锁协议,则对这些事务的所有并行调度策略都是可串行化的。因此我们得出如下结论:所有遵守两段锁协议的事务,其并行的结果一定是正确的。 需要说明的是,事务遵守两段锁协议是可串行化调度的充分条件,而不是必要条件。即可串行化的调度中,不一定所有事务都必须符合两段封锁协议。例如,在下图中,(a)和(b)都是可串行化的调度,但(a)遵守两段锁协议,(b)不遵守两段锁协议。
死锁问题在操作系统和一般并行处理中已做了深入研究,但数据库系统有其自己的特点,操作系统中解决死锁的方法并不一定合适数据库系统。 目前在数据库中解决死锁问题主要有两类方法,一类方法是采取一定措施来预防死锁的发生,另一类方法是允许发生死锁,采用一定手段定期诊断系统中有无死锁,若有则解除之。 1死锁的预防 在数据库系统中,产生死锁的原因是两个或多个事务都已封锁了一些数据对象,然后又都请求对已为其他事务封锁的数据对象加锁,从而出现死锁等待。防止死锁的发生其实就是要破坏产生死锁的条件。预防死锁通常有两种方法。 ●一次封锁法 一次封锁法要求每个事务必须一次将所有要使用的数据全部加锁,否则就不能继续执行。例如,在上图的例子中,如果事务T1将数据对象A和B一次加锁,T1就可以执行下去,而T2等待。T1执行完后释放A,B上的锁,T2继续执行。这样就不会发生死锁。 一次封锁法虽然可以有效地防止死锁的发生,但也存在问题。第一,一次就将以后要用到的全部数据加锁,势必扩大了封锁 的范围,从而降低了系统的并发度。第二,数据库中数据是不断变化的,原来不要求封锁的数据,在执行过程中可能会变成封锁对象,所以很难实现精确地确定每个 事务所要封锁的数据对象,只能采取扩大封锁范围,将事务在执行过程中可能要封锁的数据对象全部加锁,这就进一步降低了并发度。 ●顺序封锁法 顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序执行封锁。在上例中,我们规定封锁顺是 A,B,T1和T2都按此顺序封锁,即T2也必须先封锁A。当T2请求A的封锁时,由于T1已经封锁住A,T2就只能等待。T1释放A,B上的锁后,T2 继续运行。这样就不会发生死锁。 顺序封锁法同样可以有效地防止死锁,但也同样存在问题。第一,数据库系统中可封锁的数据对象及其众多,并且随数据的 插入、删除等操作而不断地变化,要维护这样极多而且变化的资源的封锁顺序非常困难,成本很高。第二,事务的封锁请求可以随着事务的执行而动态地决定,很难 事先确定每一个事务要封锁哪些对象,因此也就很难按规定的顺序取施加封锁。例如,规定数据对象的封锁顺序为A,B,C,D,E。事务T3起初要求封锁数据 对象B,C,E,但当它封锁B,C后,才发现还需要封锁A,这样就破坏了封锁顺序。 可见,在操作系统中广为采用的预防死锁的策略并不很适合数据库的特点,因此DBMS在解决死锁的问题上更普遍采用的是诊断并解除死锁的方法。 2、死锁的诊断与解除 数据库系统中诊断死锁的方法与操作系统类似,即使用一个事务等待图,它动态地反映所有事务的等待状况。并发控制子系统周期性地(比如每隔1分钟)检测事务等待图,如果发现图中存在回路,则表示系统中出现了死锁。关于诊断死锁的详细讨论请参阅操作系统的有关书籍。 DBMS的并发控制子系统一旦检测到系统中存在死锁,就要设法解除。通常采用的方法是选择一个处理死锁代价最小的事务,将其撤销,释放此事务持有的所有的锁,使其他事务能继续运行下去。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多