封锁技术可以有效地解决并行操作的一致性问题,但也带来一些新的问题,如活锁、死锁和不可串行化调度等。使用一次封锁法、顺序封锁法和两段锁协议可以有效避免这些问题。
(一)活锁和死锁
如果数据库中的信息加锁一致的话,加密的结果可能是活锁或死锁。
1.活锁
如果事务T针对数据库中的信息R执行加密操作,同时,事务2也做出同样的申请,事务T2和T3也做出同样的申请。在事务T1申请解除加在信息对象R上的密钥后,数据库会优先通过T3的申请,T2还需要继续进行等待。如果事务T4也做出相同的请求,要求对信息R执行封锁操作,数据库会通过T4的请求,所以T2还是不能实现封锁数据对象的操作。这类多个事务要求执行同样的操作,其中某个事务用户一直等待的情况被称为活锁。
2.死锁
如果事务T1已经针对数据对象A执行了封锁操作,事务T2已经对数据对象B执行了封锁操作,然后事务T1又向数据库申请对数据对象B执行封锁操作,但因为事务T2已经对数据对象B执行了封锁操作,所以要等待事务T2解除对数据对象B的封锁操作后,才能执行对数据对象B的封锁操作。紧接着,事务T2向数据库申请对数据对象A执行封锁操作,但由于事务T1已经对数据对象A执行了封锁操作,所以事务T2需要等待事务T1解除对数据对象A的封锁操作后,才能执行对数据对象A的封锁操作。这导致了事务T1与事务T2一直处在互相等待的形势,并且这种复杂的状况难以解除,两者始终处在交错的矛盾局面。这种状况被称为死锁。
当前,针对死锁局面,数据库系统有相关的解决方式,主要包含两类方法:一类是做好预防工作,避免死锁状况的发生;另一类是实行定期检查工作,如果发现死锁状况,则采取一定手段将其清除。
在数据库系统中,导致死锁状况发生的原因主要是,已经针对某些数据对象执行封锁操作的多个事务又向数据库申请封锁其他已经被加锁的数据对象,形成僵持等待的矛盾局面,用户可以采取破坏手段来避免死锁的发生。
(二)预防死锁
避免死锁局面发生的手段主要有以下两个方面。
1.一次封锁法
一次封锁法是指每项事务在执行封锁操作时,必须对全部数据对象都加锁,否则不能继续使用数据库。例如,事务A针对数据对象R1和R2执行封锁操作,事务A就可以继续进行接下来的操作,事务T2则继续等待。在事务T1解除对数据对象R1和R2的封锁操作后,由事务T2继续执行封锁操作。这样就能避免死锁状况的发生。
一次封锁法虽然可以有效防止死锁的发生,但也存在问题。第一,一次就将以后要用到的全部数据加锁,势必扩大了封锁的范围,降低了系统的并发度。第二,数据库中数据是不断变化的,不在封锁范围内的数据对象被执行封锁操作,对于时刻变化的数据较难精准确定执行封锁操作的对象,所以只能进一步扩充封锁的广度,划分出事务在工作过程中所要封锁的对象,并针对数据对象执行全面封锁,但很大程度上会降低事务的并行。
2.顺序封锁法
顺序封锁法是预先对数据对象规定一个封锁顺序,所有事务都按这个顺序实行封锁。例如在B树结构的索引中,可规定封锁的顺序必须是从根结点开始,然后是下一级的子结点,逐级封锁。
顺序封锁法同样可以有效地防止死锁,但同样存在问题。第一,数据库系统中可封锁的数据对象众多,并且随数据的插入、删除等操作而不断地变化,要维护这样极多而且变化的资源的封锁顺序非常困难,成本也较高。第二,事务执行封锁操作的情况是随着执行工作而随时产生变化的,封锁的数据对象较难确定,所以,较难按照数据库所规定的的数据对象次序执行封锁操作。例如,既定的封锁对象次序为A、B、C、D、E,事务T3先针对数据对象B、C、E执行封锁操作,但在执行封锁操作过后,察觉还需要对数据对象A执行封锁操作,这种情况就会扰乱封锁秩序。所以,在数据库运行工作中广泛运用的避免死锁产生的方式并不是适宜的方案,而DBMS模型在处理死锁时采用的检查解除方式较为合适。(https://www.xing528.com)
数据库判断死锁的途径与操作系统相似,大多数情况下采用超时和视图的手法。DBMS模型如果检测到数据库中存在死锁,就会尽力解除死锁。为了提高效率,节约成本,数据库通常选取解除死锁耗费最低的事务对其执行解除死锁操作,并将事务中的死锁全部释放,为其他事务的运行工作创造机会。同时,也要及时取消对相关事务的更改操作。
(三)并发调度的可串行性
计算机系统对并发事务中并发操作的调度是随机的,而不同的调度可能会产生不同的结果。那么,应如何判断哪个结果是正确的呢?
数据库系统对事务并行运作的数据对象的调度是任意的,不一致的调度所引发的结果也是各异的。那么,应怎样衡量结果正确与否呢?
如果一项事务在执行任务过程中没有与之一同操作的事务,那么该项事务就不会受到其他事务的影响,所以该项事务执行工作的结果是无误的。如果多个事务共同执行工作的结果与独立操作的结果相一致,那么这种调度策略就称为可串行化(Serializable)调度,反之称为不可串行化调度。可串行性(Serializability)是并发事务正确性准则。为了保证并发操作的正确性,DBMS的并发控制机制必须提供一定的手段来保证调度是可串行化的。两段锁(Two- Phase Locking,2PL)协议就是保证并发调度可串行性的封锁协议。
(四)两段锁协议
顾名思义,两段锁协议是指数据库事务在执行封锁和解锁工作时,要分两个阶段进行操作。
1.事务在针对数据对象执行读取、修改操作时,要先向数据库申请封锁操作。
2.在解除一项封锁操作时,事务不需要进行申请便能对该数据执行封锁操作。
两段锁协议将事务的执行工作分为两个阶段:第一个阶段是事务向数据库请求允许执行封锁操作,这一阶段也称作扩展阶段,此时,事务能够针对任意数据对象执行任何类型的封锁操作,但不具备解锁能力;第二个阶段是解除封锁阶段,也称作收缩阶段,这一时期,事务能够解除任意数据对象上的任意类别的封锁,但不具备封锁能力。从此处可以发现,如果全部事务都执行两段锁协议,事务的运行模式就都是可以相互协调进行的。所以我们可以得出:事务如果执行两段锁协议,那么它的运行结果是无误的。
需要进一步阐明的是,事务执行两段锁协议能够推进可串行协作的进程,但不是可串行协作的必需环节。也就是说,在可串行协作中,两段锁协议并不是所有事务执行任务的必需品。
此外,需要加以关注的问题是,两段锁协议与预防死锁的一次封锁法是存在差异的。一次封锁法是指事务在执行任务前,要一次性地将所有运行过程涉及的信息封锁起来,否则就不可以继续本次工作。所以,一次封锁法的内涵就是两段所协议。在运用两段锁协议的过程中,不需要封锁全部信息,这就容易导致死锁的产生。
(五)封锁粒度
封锁粒度是指执行封锁操作所面向的对象的大小。封锁对象的单元类型可以是逻辑性的,也可以是物理单元。以信息系统关系为例,执行封锁操作所面向的对象逻辑单元类别可能是属性值或属性值的结合、元组层级、关系,甚至是整个数据库系统,或者是数据页、板块等物理单元。
封锁粒度与数据库系统的协调运作有着紧密的联系。数据库系统中封锁对象的数量与封锁粒度的大小呈反比关系:粒度大的系统,封锁对象数量较少,协调运作程度就越小,数据库的资源耗费也较小;反之,粒度小的系统,并行运作程度大,资源耗费就较多。所以,如果数据库系统具备充足的封锁单元,事务在执行任务时的选择范围就较广。在明确封锁粒度时,要综合封锁体系和协调运作等元素,确定合理的资源耗费量和协调运作模式,从而取得理想的成果。大体来说,用户可以根据处理对象的类别,选择适宜的封锁单元,处理较多元祖层级信息的用户可以选取关系为操作体系,处理较多关系的大量元组层次的用户可以选取数据库为操作体系,处理部分元组层级信息的用户可以选取元组为封锁体系,进而提高工作效率。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。
