某抢红包软件规定发红包人可以一次抛出多个红包,由多个人来抢。要求每个抢红包的人最多只能抢到同一批次中的一个红包,且存在多个人同时抢同一红包的情况。给定的红包关系模式如下: Red(ID,BatchID,SenderID,Money,Receiver

admin2018-04-19  38

问题 某抢红包软件规定发红包人可以一次抛出多个红包,由多个人来抢。要求每个抢红包的人最多只能抢到同一批次中的一个红包,且存在多个人同时抢同一红包的情况。给定的红包关系模式如下:
    Red(ID,BatchID,SenderID,Money,ReceiverID)
    其中ID唯一标识每一个红包;BatchID为发红包的批次,一个BatchID值可以对应多个ID值;SenderID为发红包人的标识;Money为红包中的钱数;ReceiverID记录抢到红包的人的标识。
    发红包人一次抛出多个红包,即向红包表中插入多条记录,每条记录表示一个红包,其ReceiverlD值为空值。
    抢某个红包时,需要判定该红包记录的ReceiverlD值是否为空,不为空时表示该红包已被抢走,不能再抢,为空时抢红包人将自己的标识写入到ReceiverlD字段中,即为抢到红包。
下面是用SQL实现的抢红包程序的一部分,请补全空缺处的代码。
    CREATE PROCEDURE ScrambleRed(IN BatchNo VARCHAR(20),  一一红包批号
    IN RecvrNo VARCHAR(20))--接收红包者ID
    BEGIN
    一一是否已抢过此批红包
    if exists ( SELECT * FROM Red
    WHERE BatchID=BatchNo AND ReceiverID=RecvrNo)then
    return-1;
    end if;
    一一读取此批派发红包中未领取的红包记录ID
    DECLARE NonRecvedNo VARCHAR(30);
    DECLARE NonRecvedRed CURSOR FOR
    SELECT ID
    FROM Red
    WHERE BatchID=BatchNo AND ReceiverID IS NULL;
    一一打开游标
    OPEN NonRecvedRed;
    FETCH NonRecvedRed INTO NonRecvedNo;
    while not error
    --抢红包事务
    BEGIN TRANSACTION;
    //写入红包记录
    UPDATE Red SET ReceiverID=RecvrNO
    WHERE ID=NonRecvedNo AND ____(a)____;
    //执行状态判定
if<修改的记录数>=1 then
   COMMIT;
    ____(b)___;
    return 1;
    else
    ROLLBACK;
    end if;
    ____(c)___;
    end while;
    一一关闭游标
    CLOSE NonRecvedRed;
    return 0;
END

选项

答案(a)ReceiverlD ISNULL (b)CLOSE NonRecvedRed (c)FETCH NonRecvedRed INTO NonRecvedNo

解析 本问题是用存储过程编写的抢红包事务程序。用户通过调用该存储过程完成抢红包操作。因此,存储过程先查询该用户是否己抢过此批次的红包;然后以游标的方式读取到此批次当前所有未抢的红包(可能是多个),以事务的方式对游标中的当前记录写入用户ID。由于多人同时抢红包,游标所查询到的未抢红包,可能在写入用户ID时,已经被其他人写入,故写入程序应该添加条件“ReceiverlD值为空”,即(a)处应填入“ReceiverlD IS NULL”。如果出现两个及以上用户同时对同一条记录写入,此时会由DBMS进行并发控制,保证第一个响应的用户写入不被覆盖。
    根据抢红包规则,一个用户只能抢到一批红包中的一个,因此成功抢到红包后(成功更新一条红包记录),应该退出程序,不能进入下一轮循环再去抢下一个红包。程序中使用了游标,在退出程序前应该关闭游标,因此(b)处应该填写关闭游标的指令“CLOSENonRecvedRed”。
    游标操作循环体中的最后一条指令应该是推进游标指针,故(c)处应填写“FETCH NonRecvedRed INTO NonRecvedNo”。
转载请注明原文地址:https://jikaoti.com/ti/rVN7FFFM
0

相关试题推荐
随机试题
最新回复(0)