问答题 阅读下列说明,根据要求回答问题。
[说明]
某大中型电器商场仓库对货物的存取由多台配送车自动化完成,该仓库有多个入口和出口。当空配送车进入该仓库时,从仓库入口处由配送控制系统查询相应电器放置的货架位置(假设每台电器占用唯一的货架位置);当配送车装载货物从出口驶出时,系统将相应的货架位置标记设置为空。
假设实现电器商场仓库系统管理的伪指令如表所示。
伪指令含义
伪指令 说明
Get() 返回一个相应货物放置的货架位置。若当前相应货物放置的货架位置均为空,则返回空值NULL。
例如X=Get(),表示读取相应货物放置的货架位置到变量X中
Writ(X,0) 置相应的货架位置X状态为空
Writ(X,1) 置相应的货架位置X状态为非空
根据上述描述,在商场仓库入口处的伪代码程序如下。
x=Get();
IF x=NULL THEN return 0;
Writ(x,1);

问答题 若两辆配送车在不同的入口处同时执行上述代码,则可能会出现什么问题?请用100字以内的文字简要说明。
【正确答案】这是一道要求读者掌握在并发情况下,造成数据的不一致性问题的综合分析题。
依题意,若两辆配送车在不同的入口处同时执行商场仓库入口处的伪代码程序,可能会出现两辆配送车同时申请到同一个存放相应电器的货架位置,同时到该货架位置装载货物,进而都将其置为占用状态的冲突现象。
【答案解析】
问答题 为保证仓库入口处伪代码正确地并发执行,因此引入共享锁指令SLock(T)和独占锁指令xLock(T)对表T进行加锁;Upgrade(T)用于对表T所加的共享锁升级为独占锁;解锁指令Unlock(T)用于对表T进行解锁。
(1)请修改上述入口处的伪代码程序,使其满足2PL协议。
(2)满足2PL协议的仓库入口处的伪代码程序,在并发执行时是否会产生死锁?若是,给出一个产生死锁的调度;若不是,请简要说明理由。
【正确答案】这是一道要求读者掌握2PL协议实际应用的综合理解题,本试题的解答思路如下。
(1)2PL协议规定:读数据前加S锁,事务结束时释放;写数据前加X锁,事务结束时释放;当要修改数据时,事务应对自己加的S锁升级为X锁。
为保证入口处伪代码正确地并发执行,引入共享锁指令SLock(T)和独占锁指令XLock(T)对表T进行加锁;Upgrade(T)用于对表T所加的共享锁升级为独占锁;解锁指令Unlock(T)用于对表T进行解锁。满足2PL协议入口处的伪代码程序如下。
SLock(T);
x=Get();
IF x=NULL THEN return 0;
Upgrade(T);
Writ(x,1);
Unlock(T);
(2)2PL协议解决的是事务并发时的正确调度,并不能解决死锁问题。通常,死锁问题是由数据库管理系统(DBMS)进行检测和解除的。因此,满足2PL协议的入口处的伪代码程序,在并发执行时还有可能会产生死锁。例如,一个产生死锁的调度示例如表所示。
产生死锁的调度示例
T1 T2
SLock(T);
x=Get();
SLock(T);
x=Get();
IFx=NULLTHEN return 0;
Upgrade(T); IF X=NULLTHEN return 0;
等待 Upgrade(T);
等待 等待
等待 等待
... ...
【答案解析】
问答题 若货架位置表的关系模式为:storage_rack(storage_rackno,isused),其中storage_rackno为货架位置编号,isused为货架位置标志,0为空,1为非空。
下面是用E-SQL语句实现的查询货架位置的函数Get(),请将(1)~(5)空缺处的代码补充完整。
SET TRANSACTION ISOLATION LEVEL SERIALI ZABLE
EXEC SQL DECLARE getblk CURSOR FOR
select (1)
(2)
(3) ;
EXEC SQL OPEN getblk;
EXEC SQL FETCH getblk INTO:Hparkno;//Hparkno为已声明的主变量
IF SQLCA.sqlcode=350 THEN
EXEC SQL CLOSE getblk;
Return NULL;
ELSE
(4) ;
return: (5) ;
END IF
【正确答案】这是一道要求读者掌握2PL协议理论、SQL中的隔离级别和嵌入式SQL的编程实践题。
依题意,在用E-SQL语句实现的查询货架位置的函数Get()中,(1)~(3)空缺处需要补充的是游标定义中的查询部分;(4)和(5)空缺处需要补充的是关闭游标和函数返回值部分。函数Get()完整的程序代码如下:
SET TRANSACTION ISOLATl0N LEVEL SERIALIZABLE
EXEC SQL DECLARE getblk CURSOR FOR
select storage_rackno
from storage rack
where isused=0;
EXEC SQL OPEN getblk;
EXEC SQL FETCH getblk INTO:Hparkno;//Hparkno为已声明的主变量
IF SQLCA. sqlcode=100 THEN
EXEC SQL CLOSE getbl k; Return NULL;
ELSE
EXEC SQL CLOSE getblk;
return: Hparkno;
END IF
【答案解析】