閱讀下列說(shuō)明,回答問(wèn)題 1 和問(wèn)題 2 ,將解答填入答題紙的對(duì)應(yīng)欄內(nèi)。
【說(shuō)明】
某搶紅包軟件規(guī)定發(fā)紅包人可以一次拋出多個(gè)紅包,由多個(gè)人來(lái)?yè)尅R竺總€(gè)搶紅包的人最多只能搶到同一批次中的一個(gè)紅包,且存在多個(gè)人同時(shí)搶同一紅包的情況。給定的紅包關(guān)系模式如下:
Red(ID,BatchID,SenderID,Money,ReceiverID)
其中 ID 唯一標(biāo)識(shí)每一個(gè)紅包; BatchID 為發(fā)紅包的批次,一個(gè) BatchID 值可以對(duì)應(yīng)多個(gè) ID 值;SenderID 為發(fā)紅包人的標(biāo)識(shí);Money 為紅包中的錢(qián)數(shù); ReceiverID 記錄搶到紅包的人的標(biāo)識(shí)。
發(fā)紅包人一次拋出多個(gè)紅包,即向紅包表中插入多條記錄,每條記錄表示一個(gè)紅包, 其 ReceiverID 值為空值。
搶某個(gè)紅包時(shí),需要判定該紅包記錄的 ReceiverID 值是否為空,不為空時(shí)表示該紅包己被搶走,不能再搶?zhuān)瑸榭諘r(shí)搶紅包人將自己的標(biāo)識(shí)寫(xiě)入到 ReceiverID 宇段中,即為搶到紅包。
【問(wèn)題 1】 (9分)
引入兩個(gè)偽指令 a = R(X) 和 W(b,X) 。其中a = R(X) 表示讀取當(dāng)前紅包記錄的 ReceiverID 字段(記為數(shù)據(jù)項(xiàng) X) 到變量 a 中, W(b,X)表示將搶紅包人的唯一標(biāo)識(shí) b 的值寫(xiě)入到當(dāng)前紅包記錄的 ReceiverID 字段(數(shù)據(jù)項(xiàng) X) 中,變量 a 為空值時(shí)才會(huì)執(zhí)行 W(b,X) 操作。假設(shè)有多個(gè)人同時(shí)搶同一紅包(即同時(shí)對(duì)同一記錄進(jìn)行操作),用 ai=Ri (X)和 Wi(bi, X)表示系統(tǒng)依次響應(yīng)的第i個(gè)人的搶紅包操作。假設(shè)當(dāng)前數(shù)據(jù)項(xiàng) X 為空值,同時(shí)有三個(gè)人搶同一紅包,則
(1)如下的調(diào)度執(zhí)行序列:
a1 =R1, a2 = R2(X),W1(b1 ,X),W2(b2,X), a3 = R3(X)
搶到紅包的是第幾人?并說(shuō)明理由。
(2)引入共享鎖指令 SLocki(X)、獨(dú)占鎖指令XLocki(X)和解鎖指令 ULocki(X) ,其中下標(biāo) i表示第 i個(gè)搶紅包人的指令。如下的調(diào)度執(zhí)行序列:
SLock1(X),a1 = R1(X),SLock2(X),a2 = R2(X),XLock1(X)......
是否會(huì)產(chǎn)生死鎖?并說(shuō)明理由。 (3)為了保證系統(tǒng)第一個(gè)響應(yīng)的搶紅包人為最終搶到紅包的人,請(qǐng)使用上述。)中引入的鎖指令,對(duì)上述(1)中的調(diào)度執(zhí)行序列進(jìn)行修改,在滿足 2PL協(xié)議的前提下,給 出一個(gè)不產(chǎn)生死鎖的完整的調(diào)度執(zhí)行序列。
【問(wèn)題 2】 (6分)
下面是用 SQL實(shí)現(xiàn)的搶紅包程序的一部分,請(qǐng)補(bǔ)全空缺處的代碼
CREATE PROCEDURE ScrambleRed (IN BatchNo VARCHAR(20) , --紅包批號(hào)
(IN RecvrNo VARCHAR(20)) 一接收紅包者
BEGIN
--是否已搶過(guò)此批紅包
if exists( SELECT * FROM Red
WHERE BatchID = BatchNo AND ReceiverID = RecvrNo) thm
return -1;
end if;
---讀取此批派發(fā)紅包中未領(lǐng)取的紅包記錄ID
DECLARE NonRecvedNo VARCHAR(30);
DECLARE NonRecvedNo CURSOR FOR
SELECT ID
FROM Red
WHERE BatchID = BatchNo AND ReceiverID IS NULL;
-打開(kāi)游標(biāo)
OPEN NonRecvedRed;
FETCH NonRecvedRed INTO NonRecvedNo;
while not error
一搶紅包事務(wù)
BEGIN TRANSACTION;
//寫(xiě)入紅包記錄
UPDATE RED STE RECDIVER ID =RecvrNo
WHERE ID = nonRECVED AND(a)
//執(zhí)行狀態(tài)判定
If<修改的記錄數(shù)>= 1 THEN
COMMIT;
(b);
Return 1;
Else
ROLLBACK;
End if;
(c);
End while
--關(guān)閉游標(biāo)
CLOSE NonRecved RD
Return 0;
END