摘要数据库锁技术作为保证数据并发性和数据一致性的有效手段,是RDBMS的要害技术之一。作 者以Oracle7数据库在编组站的应用为例,对关系数据库治理系统的数据库锁的 种类及其应用进行了研究。
要害词并发控制DML锁数据库ORACLE 7
1ORACLE数据库中的各类锁
ORACLE在各种不同的开发应用环境中,根据封锁对象和封锁方式的不同,可划分出多种不同 类型的锁,见表1。
表1不同类型的锁
实际上,ORACLE中任何一种锁的操作最终都是调用封锁治理程序来完成,而它是ORACLE内核 数据库中的一个组成部分,具有LOCK与UNLOCK两大功能。
1.1LOCK算法
1.1.1一般调用格式:LOCK(s-jd,locktype,lockmode,Tid,NOWAIT)
其中:s-jd是封锁对象的内部标识
locktype是封锁类型
lockmode是封锁模式
Tid是事务对象标识号
NOWAIT:为“N”时等待,为“Y”时不等待
1.1.2基本步骤
a. L.1 申请空队列块,若暂不为空,则继续循环检测,时间等待10 s;若申请不到,给出 错误信息;若申请到了,则填写封锁队列块;
b. L.2 在活动队列中查找有没有与s-jd相同的块,若无,则填写ACHIVE标志,然后挂入 活动队列,并退出。若有则进入L.3进行判定;
c. L.3 LOCKTYPE=“DDL”吗?若是,即按字典锁相容性进行判定;若冲突,则给出错误信 息 ;若不冲突,则填写ACHIVE标志,然后挂入活动队列并返回;当LOCKTYPE=“DML”时,则转 入L.4,若LOCKTYPE为内部锁时,则陷入等待;
d. L.4进行DML锁相容性判定,若不冲突,填写ACHIVE标志,然后插入活动锁队列并返回; 若冲突,则判定其它Tid是否相同,若相同,给出出错信息;若不同,则进入L.5;
f. L.5进入判定NOWAIT,当为“N”时,则退出并给出错误信息,若为“Y”时,则进入死 锁 检测;若死锁,则给出错误信息;若不出现死锁,则填写WAIT标志,同时还填相应的WAIT -POINT,然后插入等待队列并返回。
1.2UNLOCK的算法
一般调用格式:UNLOCK(Tid)
a.U.1在活动锁队列中查找拥有Tid的锁,然后将该锁释放,并挂入空闲队列;
b.U.2等待锁队列中唤醒(激活)相应的等待锁。
1.3死锁检测算法
在ORACLE中提供了有效的死锁检测机制。在检测死锁中存在两个问题:(1)死锁判定, 即等 待回路的判定;(2)选择退出事务。选择退出事务的原则是执行修改数目最小者,即以 记录 为单位进行增、删和改记录个数最少的事务被选为退出事务。下面给出死锁处理的基本算法 :
. TD.1-当新的等待锁到来时,即把Tid放入集合S中,然后取WAIT-POINT赋于P;
. TD.2-判定P.Tid ∈ S吗?若是,则进行调用回收资源,并唤醒相应事务,然后返回, 否则进入TD.3;
. TD.3-在等待队列中寻找P.Tid所拥有的等待块,若有,则把P.Tid并入集合S中,同时 将WAIT-POINT赋于P,然后转到TD.2继续循环;否则,不发生死锁,返回。
从以上锁的分类以及LOCK与UNLOCK的算法中,可以看出ORACLE核心实现的封锁治理程序与死 锁诊断是简便灵活及有效的。
2SYIS的并发控制技术
2.1事务控制
事务控制SYIS为事务控制提供3种调用方法:开始事务、中止事务、结束事务。开始事 务用以标志一组逻辑上有关的SYIS的开始;结束事务用来完成一个事务并对受影响的数据文 件做适当的修改;中止事务用来删除自一个活动的事务开始以来执行的所有操作并终止这个 事务。任何时候当应用访问事务内的基表时,ORACLE就为该应用锁定该基表,直到事务结束 或异常终止,而其他用户可以在非事务内和非锁定状态下读该基表。
一般情况下,当开始事务时,用户可以指定为等待锁定或非等待锁定。当指定为等待锁定时 ,假如有2台终端试图访问同一个事务内的文件,ORACLE将锁定第二台终端,直到第一个用 户结束或中止事务,若指定为非等待锁,则第二个用户可以检测到死锁的信息,这时系统管 理员作出相应的处理。由于事务操作是对基表级锁定,因此很轻易产生死锁。
2.2被动并发性
被动并发性控制方法答应读取与更新记录而不用执行任何锁定或事务,如 果一个记录在用户的程序读取的时间或试图更新的时间之间有变动,则返回错误信息。
2.3记录锁定
当SYIS的用户访问一个基表内的记录时,用户可以锁定希望封锁的记录。一 旦被用户指定封锁的记录,其他用户可以不带锁定地读取记录。
记录锁定有单个和多个锁定。对这两类记录可指定为等待锁定或非等 待锁定。具体办法是把一个值与任一“取”、“异步”、“打开”或者“开始事务”的操作 码相加,列出下表的锁定偏置值
表2锁定偏置值
对于单个记录锁定,在某一时刻只能锁定基表中的一个记录,若对这个基表发出带有一个锁 定的另一个“取”的操作、更新或删除这个被锁定的记录,或者发出一个“解锁”命令,于 是ORACLE就解放这个锁定。
对于多个记录锁定,答应一个应用在一个基表中锁定多个记录,并随后在必要时对那些 记录进行更新或删除,这于单个记录不同的是更新记录或发出另一个带有多记录锁定的“取 ”操作时,不解锁该记录,只有通过显式“解锁”操作,这个锁才被解除。 这种等待解锁 不返回状态码,直到该锁定成功,而非等待锁定,当另一个用户保持记录锁定时,立即给用 户返回一个忙的状态。
由于DML语句会自动获得所需要的锁,因此,在应用程序中,可以直接使用DML语句,而不必 考虑数据库锁,但是,由于数据库锁是自动获得的,因此用户无法对其进行判定,尤其是在 有长大事务或者对基表DML操作较多的应用中,轻易出现长时间等待锁的情况,如图1所示。
图1长时间等待锁情况
事务2在时间2对DEPT表进行更新,但由于事务1对基表DEPT有锁,故须等待,直到时间3时事 务1回退或提交,事务2的语句才能执行,假如时间1与时间2间隔较长,则事务2将出现 较长的等待时间。
为了避免自动使用数据库锁造成的事务长时间等待其他事务释放锁的情况,可以采用手工获 得数据库锁的办法,手工获得数据库锁的方法是在对数据更新操作(INSERT、UPDATE、DELET E)之前,先利用获得锁的DML语句来检查所要操作的基表是否有数据锁,再决定是否进行进 一步的数据更新操作。见图2。
图1长时间等待锁的情况
由于在时间1时事务1对基表DEPT加锁,因此,在时间2时事务1手工获得锁失败(产生ORACLE 例外ORA-00054),表明对基表DEPT的deptno=10的记录的更新操作与其他事务冲突,而当时 间3事务1进行回退或提交后,事务2就可以实现对DEPT基表的手工加锁(时间4)。这样,便可 以根据手工获得锁的情况在决定下一步的操作而不必一直等待其他事务释放所需要的锁。
3两阶段非等待锁定机制
在SYIS中,称交易为事务,现在将有关概念术语列述如下:(1)事务:在批处理或运程批处理中的一个作业或作业步;或一个工作站与完成一个非凡动 作或结果的其它设备间的一次数据交换;或对数据库文件的一组更改;(2)事务粒度:一次事务中所占有的共享资源量的多少;(3)事务回滚:事务失败时,要恢复事务所执行的所有动作到事务初始状态,就象事务没有发生 过一样;(4)事务封锁:为执行事务中的操作,对需要的共享资源进行的封锁;(5)事务提交:事务成功时,使操作及结果数据能有效地操作。
在传统的两步锁并发控制协议中,事务的执行分两个阶段:第一阶段获得所有的数据库源, 即对所有的数据加锁;第二阶段对数据资源解锁。在事务第一次解锁后,就不能再对数据资 源加锁。这样,实际上,有一些数据资源被不必要地锁住了太长时间,显然,这造成了数据 资 源的闲置。利用我们讨论的数据库一致性划分,可以在一定程度上解决问题:一个事务对于 同一个原子数据集中的数据项满足前面所述的加锁解锁的时序关系。而对一个原子数据集中 的数据开始解锁后,同一事务还可以对其它原子数据集的数据加锁。这在一定程度上避免了 资源的闲置,提高了并发度,相应地提高了系统的性能。
在嵌套事务模型中,往往是父事务只访问一个原子数据的数据集中的数据,而子事务访问另 一个原子数据集的数据。这样,可以只保证各原子数据集的一致性,从而也就保证了整个数 据库的一致性。
在ORACLE数据库中,数据的一致性、完整性、可恢复性和并发性,使事务成为数据库系统的 一个基本的工作单位,具体说是对访问的不可再分性的操作系统。具有以下4个基本性质: a.事务的不可再分性;b.事务的持久性;c.事务的串行性;d.事务的隔离性。
二阶段非等待封锁机制的实现是在SYIS提供的事务和封锁调用基础上,在应用程序级解决了 可能出现死锁的问题,无论数据库系统是否提供了死锁检测和保护功能,此机制都能很好地 处理各进程之间的事务并发控制。
定义:对所有事务都满足下述两条件的协议被成为二阶段封锁协议:(1)在对任何数据单元执行操作之前,事务首先对该数据单元加锁;(2)若对一个数据单元开锁后,事务不再对任何其他单元进行加锁。
定理:满足二阶段封锁协议的事务的并发执行是可串行化的,即保证了事务的串行性。
二阶段非等待锁定机制按以下步骤实现:LN.0 初值V.delay=0;LN.1 延时2V.delay;LN.2 非等待开始事