201705数据库下午真题
第 1 题
某医疗器械公司作为复杂医疗产品的集成商,必须保持高质量部件的及时供应。为了实现这一目标,该公司欲开发一采购系统。系统的主要功能如下:
1.检查库存水平。采购部门每天检查部件库存量,当特定部件的库存量降至其订货点时,返回低存量部件及库存量。
2.下达采购订单。采购部门针对低存量部件及库存量提交采购请求,向其供应商(通过供应商文件访问供应商数据)下达采购订单,并存储于采购订单文件中。
3. 交运部件。当供应商提交提单并交运部件时,运输和接收(S /R)部门通过执行以下三步过程接收货物:
(1)验证装运部件。通过访问采购订单并将其与提单进行比较来验证装运的部件, 并将提单信息发给S/R 职员。如果收货部件项目出现在采购订单和提单上,则已验证的提单和收货部件项目将被送去检验。否则S /R职员提交的装运错误信息生成装运错误通知发送给供应商。
(2)检验部件质量。通过访问质量标准来检查装运部件的质量,并将已验证的提单发给检验员。如果部件满足所有质量标准,则将其添加到接受的部件列表用于更新部件库存。如果部件未通过检查,则将检验员创建的缺陷装运信息生成缺陷装运通知发送给供应商。
(3)更新部件库存。库管员根据收到的接受的部件列表添加本次采购数量,与原有库存量累加来更新库存部件中的库存量。标记订单采购完成。
现采用结构化方法对该采购系统进行分析与设计,获得如图 1-1 所示的上下文数据流图和图 1-2所示的 0 层数据流图。
【问题2】(4分)
使用说明中的词语,给出图1-2中的数据存储D1-D4的名称。
【问题3】(4分)
根据说明和图中术语,补充图1-2中缺失的数据流及其起点和终点。
【问题4】(2分)
用200字以内文字,说明建模图1-1 和图1-2时如何保持数据流图平衡。 **答案与解析** - 试题难度:较难 - 知识点:软件工程>DFD与数据字典 - 试题答案:
E2:采购部
E3:检验员
E4:库管员
E5:S/R职员
【问题2】(4分)
D1:库存表
D2:采购订单表
D3:质量标准表
D4:供应商表
【问题3】(4分)
装运错误通知:P3(验证装运部件)-----E1(客户)
缺陷装运通知:P4(校验部件质量)-----E1(客户)
产品检验:P3(验证装运部件)------ P4(校验部件质量)
检查库存信息:P1(检查库存水平)-----D1(库存表)
或原有部件库存量:D1(库存表)------P5(更新部件库存)
【问题4】(2分)
父图中某个加工的输入输出数据流必须与其子图的输入输出数据流在数量上和名字上相同。父图的一个输入(或输出)数据流对应于子图中几个输入(或输出)数据流,而子图中组成的这些数据流的数据项全体正好是父图中的这一个数据流。 - 试题解析:
【问题1】
依据题干中“下达采购订单。采购部门针对低存量部件及库存量提交采购请求,向其供应商(通过供应商文件访问供应商数据)下达采购订单,并存储于采购订单文件中。”可以判断出E1为供应商。
依据题干中“检查库存水平。采购部门每天检查部件库存量,当特定部件的库存量降至其订货点店时,返回低存量部件及库存量。”,可以判断出E2为采购部。
依据题干中“通过访问质量标准来检查装运部件的质量,并将已验证的提单发给检验员。如果部件满足所有质量标准,则将其添加到接受的部件列表用于更新部件库存。”可以判断出E3为检验员。
依据题干中“库管员根据收到的接受的部件列表添加本次采购数量”可以判断出E4为库管理员。
依据题干中“如果收货部件项目出现在采购订单和提单上,则已验证的提单和收货部件项目将被送去检验。否则S/R职员提交的装运错误信息生成装运错误通知发送给供应商。”可以判断出E5为S/R职员。
【问题2】
依据题干中“更新部件库存。库管员根据收到的接受的部件列表添加本次采购数量,与原有库存量累加来更新库存部件中的库存量。”结合零层图的数据流,可以得出D1为库存表
依据题干中“下达采购订单。采购部门针对低存量部件及库存量提交采购请求,向其供应商(通过供应商文件访问供应商数据)下达采购订单,并存储于采购订单文件中。”和“更新部件库存。库管员根据收到的接受的部件列表添加本次采购数量,与原有库存量累加来更新库存部件中的库存量。标记订单采购完成”,结合零层图的数据流,可以得出D2为采购订单表,D4为供应商表。
依据题干中“检验部件质量。通过访问质量标准来检查装运部件的质量,并将已验证的提单发给检验员。如果部件满足所有质量标准,则将其添加到接受的部件列表用于更新部件库存。”,结合零层图的数据流,可以得出D3为质量标准表。
【问题3】
依据题干中“(1)中:否则S/R职员提交的装运错误信息生成装运错误通知发送给供应商。”,结合零层图可以发现缺失数据流:装运错误通知:P3(验证装运部件)-----E1(客户)
依据题干中“(2)中:如果部件未通过检查,则将检验员创建的缺陷装运信息生成缺陷装运通知发送给供应商。”,结合零层图可以发现缺失数据流:缺陷装运通知:P4(校验部件质量)-----E1(客户)
依据题干中“(1)中:如果收货部件项目出现在采购订单和提单上,则已验证的提单和收货部件项目将被送去检验。”,结合零层图可以发现缺失数据流:产品检验:P3(验证装运部件)------ P4(校验部件质量)
依据题干中“1、检查库存水平。采购部门每天检查部件库存量,当特定部件的库存量降至其订货点店时,返回低存量部件及库存量。”,结合零层图可以发现缺失数据流:检查库存信息:P1(检查库存水平)-----D1(库存表)
【问题4】
父图中某个加工的输入输出数据流必须与其子图的输入输出数据流在数量上和名字上相同。父图的一个输入(或输出)数据流对应于子图中几个输入(或输出)数据流,而子图中组成的这些数据流的数据项全体正好是父图中的这一个数据流。
第 2 题
某房屋租赁公司拟开发一个管理系统用于管理其持有的房屋、租客及员工信息。请根据下述需求描述完成系统的数据库设计。
【需求描述】
1.公司拥有多幢公寓楼,每幢公寓楼有唯一的楼编号和地址。每幢公寓楼中有多套公寓,每套公寓在楼内有唯一的编号(不同公寓楼内的公寓号可相同)。系统需记录每套公寓的卧室数和卫生间数。
2.员工和租客在系统中有唯一的编号(员主编号和租客编号)。
3.对于每个租客,系统需记录姓名、多个联系电话、一个银行账号(方便自动扣房租)、一个紧急联系人的姓名及联系电话。
4.系统需记录每个员工的姓名、类别、一个联系电话和月工资。员工类别可以经理或维修工,也可兼任。每个经理可以管理多幢公寓楼。每幢公寓楼必须由一个经理管理。 系统需记录每个维修工的业务技能,如:水暖维修、电工、木工等。
5.租客租赁公寓必须和公司签订租赁合同。一份租赁合同通常由一个或多个租客(合租)与该公寓楼的经理签订,一个租客也可租赁多套公寓。合同内容应包含签订日期、开始时间租期、押金和月租金。
【概念模型设计】
根据需求阶段收集的信息,设计的实体联系图(不完整)如图2-1 所示。
根据概念模型设计阶段完成的实体联系图,得出如下关系模式(不完整):
联系电话(电话号码,租客编号)
租客(租客编号,姓名,银行账号,联系人姓名,联系人电话)
员工 (员工编号,姓名,联系电话,类别,月工资,( a ))
公寓楼((b) ,地址,经理编号)
公寓(楼编号,公寓号,卧室数,卫生间数)
合同(合同编号,租客编号,楼编号,公寓号,经理编号,签订日期,起始日期,租期,(c ),押金)
【问题2】(4.5分)
补充逻辑结构设计中的(a)(b)(c ) 三处空缺。
【问题3】(6分)
租期内,公寓内设施如出现问题,租客可在系统中进行故障登记,填写故障描述,每项故障由系统自动生成唯一的故障编号,由公司派维修工进行故障维修,系统需记录每次维修的维修日期和维修内容。请根据此需求,对图 2-1 进行补充,并将所补充的 ER 图内容转换为一个关系模式,请给出该关系模式。 **答案与解析** - 试题难度:较难 - 知识点:数据库技术基础>E-R模型 - 试题答案:
(a)业务技能
(b)楼编号
(c)月租金
【问题3】(6分)
维修(故障编号,故障描述,维修工,维修日期,维修内容,楼编号,公寓号,租客编号)
【问题1】
依据题干中“租客租赁公寓必须和公司签订租赁合同。一份租赁合同通常由一个或多个租客(合租)与该公寓楼的经理签订,一个租客也可租赁多套公寓。合同内容应包含签订日期、开始时间租期、押金和月租金。”,说明签约应该是经理与租赁之间的,而一份租赁包括一位或多位租客,以及一个或多个公寓,所以可以考虑为:经理实体集与租赁(由租客和公寓组合成一个大的实体集)之间的联系。
在结合题干中“每个经理管多个公寓楼,每个公寓楼由一个经理管理,和一个楼有多个公寓”的描述,可以判定联系的类型为1:*
【问题2】
从题干中“系统需记录每个员工的姓名、类别、一个联系电话和月工资。员工类别可以经理或维修工,也可兼任。每个经理可以管理多幢公寓楼。每幢公寓楼必须由一个经理管理。系统需记录每个维修工的业务技能,如:水暖维修、电工、木工等”说明需要记录的属性有:姓名、类别、一个联系电话、月工资和业务技能。因此(a)处应为:业务技能。
题干中“每幢公寓楼有唯一的楼编号和地址以及每幢公寓楼必须由一个经理管理”同时管理联系没有转换成一个独立的关系,也就意味着管理联系被合并到了公寓楼的实体对应的关系中,因此,公寓楼实体对应的关系的属性应该有:楼编号、地址、经理编号;因此(b)处应该为:楼编号。
依据题干中“合同内容应包含签订日期、开始时间租期、押金和月租金。”结合关系合同(合同编号,租客编号,楼编号, 公寓号,经理编号,签订日期,起始日期,租期,(c),押金),可以得出(c)处应该为:月租金。
【问题3】
题干中“租期内,公寓内设施如出现问题,租客可在系统中进行故障登记,填写故障描述,每项故障由系统自动生成唯一的故障编号,由公司派维修工进行故障维修,系统需记录每次维修的维修日期和维修内容”
说明,维修应该与租赁(由租客和公寓组合成一个大的实体集)之间存在多对多的联系,同时需要有自己的属性:故障编号、维修日期、维修内容。
维修(故障编号,维修工,维修日期,维修内容,楼编号,公寓号,租客编号)
第 3 题
阅读下列说明,回答问题 1 至问题 3,将解答填入答题纸的对应栏内
【说明】
某社会救助基金会每年都会举办多项社会公益救助活动,需要建立一个信息系统,对之进行有效管理。
【需求描述】
1.任何一个实名认证的个人或者公益机构都可以发起一项公益救助活动,基金会需要记录发起者的信息。如果发起者是个人,需要记录姓名、身份证号和一部电话号码;如果发起者是公益机构,需要记录机构名称、统一社会信用代码、一部电话号码、唯一的法人代表身份证号和法人代表姓名。一个自然人可以是多个机构的法人代表。
2.公益救助活动需要提供详实的资料供基金会审核,包括被捐助人姓名、身份证号、 一部电话号码、家庭住址。
3.基金会审核并确认项目后,发起公益救助的个人或机构可以公开宣传并募捐,募捐得到的款项进入基金会账户。
4.发起公益救助的个人或机构开展救助行动,基金会根据被捐助人所提供的医疗发票或其他信息,直接将所筹款项支付给被捐助者。
5.救助发起者针对任一被捐助者的公益活动只能开展一次。
【逻辑结构设计】
根据上述需求,设计出如下关系模式:
公益活动(发起者编号,被捐助者身份证号,发起者电话号码,发起时间,结束时间, 募捐金额),其中对于个人发起者,发起者编号为身份证号;对于机构发起者,发起者编号为统一社会信用代码。
个人发起者(姓名,身份证号,电话号码)
机构发起者(机构名称,统一社会信用代码,电话号码,法人代表身份证号,法人代表姓名)
被捐助者(姓名,身份证号,电话号码,家庭住址)
【问题1】(6 分)
对关系“机构发起者”,请回答以下问题:
(1) 列举出所有候选键。
(2) 它是否为3NF ,用100字以内文字简要叙述理由。
(3) 将其分解为 BC 范式,分解后的关系名依次为:机构发起者1,机构发起者 2 ,……, 并用下划线标示分解后的各关系模式的主键。
【问题2】(6 分)
对关系“公益摇动 ”,请回答以下问题:
(1)列举出所有候选键。
(2)它是否为2NF ,用100字以内文字简要叙述理由。
(3)将其分解为 BC 范式,分解后的关系名依次为:公益活动1,公益活动 2 ,……, 并用下划线标示分解后的各关系模式的主键。
【问题3】(3分)
基金会根据被捐助人提供的医疗发票或其他信息,将所筹款项支付给被捐助者。可以存在分期多次支付的情况,为了统计所筹款项支付情况(详细金额和时间) ,试增加“支付记录”关系模式,用100字以文字简要叙述解决方案。
答案与解析
- 试题难度:较难
- 知识点:关系数据库>1NF至4NF
- 试题答案:
【问题1】(6分)
(1)统一社会信用代码。
(2)否,存在传递依赖 :统一社会信用代码→法人代表身份证号,法人代表身份证号→法人代表姓名。
(3)机构发起者1(机构名称,统一社会信用代码,电话号码,法人代表身份证号)主键:统一社会信用代码。
机构发起者2(法人代表身份证号,法人代表姓名)主键:法人代表身份证号。
【问题2】(6分)
(1)发起者编号+被捐助者身份证号。
(2)否:存在部分函数依赖:发起者编号→(发起者电话号码)对码(发起者编号,被捐助者身份证号)存在部分函数依赖。
(3)公益活动1(发起者编号,发起者电话号码)主键:发起者编号。
公益活动2(发起者编号,被捐助者身份证号,发起时间,结束时间,募捐金额)主键:发起者编号+被捐助者身份证号。
【问题3】(3分)
支付记录(支付编号,发起者编号,被捐助者身份证号,支付金额,支付时间,被捐助人的相关信息)(被捐助人的相关信息为医疗发票或其他信息),支付编号唯一标识每一次支付。 - 试题解析:
【问题1】
题干中“如果发起者是公益机构,需要记录机构名称、统一社会信用代码、一部电话号码、唯一的法人代表身份证号和法人代表姓名。一个自然人可以是多个机构的法人代表。”结合关系
机构发起者(机构名称,统一社会信用代码,电话号码,法人代表身份证号,法人代表姓名)
由于统一社会信用代码是唯一的,统一社会信用代码→(机构名称、电话号码、法人代表身份证号)
法人代表身份证号→法人代表姓名
所以,该关系的候选码应该为:统一社会信用代码
不是3NF,存在传递依赖,统一社会信用代码传递函数决定法人代表姓名
依照函数依赖关系可以该关系分解为:
机构发起者1(机构名称,统一社会信用代码,电话号码,法人代表身份证号)
主键:统一社会信用代码
机构发起者2(法人代表身份证号,法人代表姓名)
主键:法人代表身份证号
【问题2】
公益活动(发起者编号,被捐助者身份证号,发起者电话号码,发起时间,结束时间, 募捐金额),其中对于个人发起者,发起者编号为身份证号:对于机构发起者,发起者编号为统一社会信用代码。
题干中“任何一个实名认证的个人或者公益机构都可以发起一项公益救助活动,基金会需要记录发起者的信息。以及救助发起者针对任一被捐助者的公益活动只能开展一次”
发起者编号→发起者电话号码
(发起者编号,被捐助者身份证号)→(发起时间,结束时间, 募捐金额)
由于多个项目的起始时间可能相同,而结束时间可能不同,所以发起时间不能函数决定结束时间。同时也有可能多个项目的起始和结束时间是相同的。所以发起时间和结束时间不能函数决定一次活动。
所以其主键应该为:(发起者编号,被捐助者身份证号)
否,由于存在部分函数依赖,非主属性发起者电话号码部分函数依赖于码(发起者编号,被捐助者身份证号)
公益活动1(发起者编号,发起者电话号码)
主键:发起者编号
公益活动2(发起者编号,被捐助者身份证号,发起时间,结束时间,募捐金额)
主键:发起者编号+被捐助者身份证号
【问题3】
题干中“基金会根据被捐助人提供的医疗发票或其他信息,将所筹款项支付给被捐助者。可以存在分期多次支付的情况,为了统计所筹款项支付情况(详细金额和时间)”
在该关系中应该涉及款项是由哪个公益活动募集而来,和被捐助人,同时题干中要求增加详细金额和时间,所以应该增加金额和时间相关的属性。为了优化关系,增加支付的编码作为该关系的主码。
支付记录(支付编号,发起者编号,被捐助者身份证号,支付金额,支付时间,被捐助人的相关信息)(被捐助人的相关信息为医疗发票或其他信息),支付编号唯一标识每一次支付。
第 4 题
某公司要对其投放的自动售货机建立商品管理系统,其数据库的部分关系模式如下:
售货机: VEM(VEMno, Location) ,各属性分别表示售货机编号、部署地点;
商品: GOODS(Gno, Brand, Price) ,各属性分别表示商品编号、品牌名和价格;
销售单: SALES(Sno, VEMno,Gno,SDate,STime),各属性分别表示销售号、售货机编号、商品编号、日期和时间。
缺货单: OOS(VEMno,Gno,SDate,STime ),各属性分别表示售货机编号、商品编号、 日期和时间。
相关关系模式的属性及说明如下:
(1)售货机摆放固定种类的商品,售货机内每种商品最多可以储存10 件。管理员在每天结束的时候将售货机中所有售出商品补全
(2)每售出一件商品,就自动向销售单中添加一条销售记录。如果一天内某个售货机上某种商品的销售记录达到10 条,则表明该售货机上该商品已售完,需要通知系统立即补货,通过自动向缺货单中添加一条缺货记录来实现。
根据以上描述,回答下列问题,将 SQL 语句的空缺部分补充完整。
CREATE TABLE SALES(
Sno CHAR(8) (a)
VEMno CHAR(5) (b)
Gno CHAR(8) (c)
SDate DATE,
STime TIME);
【问题 2】 (4分)
创建销售记录详单视图 SALES_Detail ,要求按日期统计每个售货机上各种商品的销售数量,属性有 VEMno、Location 、Gno、Brand 、Price 、amount 和 SDate。为方便实现,首先建立一个视图 SALES_Total ,然后利用SALES_Total 完成视图 SALES_Detail 的定义。
CREATE VIEW SALES _Total(VEMno,Gno,SDate,amount) AS
SELECT VENno ,Gno ,SDate ,count(*)
FROM SALES
GROUP BY (d);
CREATE VIWE (e) AS
SELECT VEM.VEMno,Location ,GOODS.Gno ,Brand,Price,amount,SDate
FROM VEM,GOODS,SALES_Total
WHERE (f) AND (g)
【问题 3】 (3分)
每售出一件商品,就自动向销售单中添加一条销售记录。如果一天内某个售货机上某种商品的销售记录达到 10 条,则自动向缺货单中添加一条缺货记录。需要用触发器来实现缺货单的自动维护。程序中的 GetTime()获取当前时间。
REFERENCING new row AS nrow
FOR EACH ROW
BEGIN
INSERT INTO OOS
SELECT SALES .VENno, (j) GetTime()
FROMSALES
WHERE SALES.VEMno = nrow.VEMno AND SALES.Gno = nrow.Gno
AND SALES.SDate = nrow.SDate
GROUP BY SALES.VEMno,SALES.Gno,SALES.SDate
HAVING count(*)> 0 AND mod(count(*), 10)=0;
END
查询当天销售最多的商品编号、品牌和数量。程序中的 GetDate()获取当天日期。
SELECT GOODS.Gno ,Brand, (k)
FROM GOODS,SALES
WHERE GOODS.Gno=SALES.GNO AND SDATE =GetDate()
GROUP BY (1)
HAVING(M) (SELECT count(*)
FROM SALELS
WHERE SDATE = GetDate()
GROUP BY Gno);
【问题5】 (2分)
查询一件都没有售出的所有商品编号和品牌。
SELECT Gno ,Brand
FROM GOODS
WHERE GNO(N)
SELECT DISTINCT GNO
FROM(o);
**答案与解析** - 试题难度:较难 - 知识点:SQL语言>SELECT语句 - 试题答案:
(b)REFERENCES VEM(VEMno)
(c)REFERENCES GOODS(Gno)
【问题2】(4分)
(d)VEMno,Gno,SDate
(e)SALES_Detail(VEMno,Location,Gno,Brand,Price,Amount,SDate)
(f)VEM.VEMno=SALES_Total. VEMno
(g)GOODS.Gno= SALES_Total. Gno
f和g可以互换
【问题3】(3分)
(h)TRIGGER
(i)INSERT
(j)SALES.Gno,SALES.SDate
【问题4】(3分)
(k)COUNT(*) AS 数量
(l)GOODS.Gno,Brand
(m)COUNT(*)>=ALL
【问题5】(2分)
(n)NOT IN
(o)SALES
- 试题解析:
(a)PRIMARY KEY
(b)REFERENCES VEM(VEMno)
(c)REFERENCES GOODS(Gno)
【问题2】
本题是考查创建视图的语法:
CREATE VIEW 视图名(列名 [,· · · n])
AS SELECT 查询子句
(d)处应该制定分组的依据,由于SELECT语句后跟随了 VEMno ,Gno ,SDate这些列,所以(d)处应该列表这些列
(e)处应该为创建视图的名称:SALES_Detail(VEMno,Location,Gno,Brand,Price,Amount,SDate)
(f)和(g)处应该制定查询语句中涉及到的3个关系之间的连接条件:(f)VEM.VEMno=SALES_Total. VEMno ;(g)GOODS.Gno= SALES_Total. Gno;f和g可以互换
【问题3】
本题是考查创建触发器的语句
CREATE TRIGGER 触发器名
[{BEFORE|AFTER}]
{事件}
ON <对象名>
REFERENCING {OLD AS old}|{NEW AS new}
[FOR EACH ROW] [WHEN 条件]
{触发器执行体}
(h)处应该为关键字:TRIGGER
(i)处应该是插入数据时触发,所以应该为INSERT
OOS(VEMno,Gno,SDate, STime)共有4个属性且为全码表,INSERT语句必须插入所有列的值,因此:
(j)处应该为:SALES.Gno,SALES.Sdate
【问题4】
题干中要求返回数量,因此(k)COUNT(*) AS 数量
(l)处是分组的依据,分组的依据为商品编号,由于SELECT 后跟随了列GOODS.Gno,Brand,所以(l)处应为:GOODS.Gno,Brand
(m)处是在分组的基础上制定筛选的条件;而子查询返回的是一系列的单个属性的值的集合,应该使用>=ALL来取得最大值,所以(m)处应填写COUNT(*)>=ALL
【问题5】
依据子查询 SELECT DISTINCT GNO FROM(o);应该是从销售表中查询出有销售记录的商品编号,所以(o)处应为:SALES
(n)处为筛选条件,只有没有出现在销售表中的商品编号,也就意味着没有销售过,因此(n)处应为:NOT IN
### 第 5 题
阅读下列说明,回答问题 1 和问题 2 ,将解答填入答题纸的对应栏内。
【说明】
某抢红包软件规定发红包人可以一次抛出多个红包,由多个人来抢。要求每个抢红包的人最多只能抢到同一批次中的一个红包,且存在多个人同时抢同一红包的情况。给定的红包关系模式如下:
Red(ID,BatchID,SenderID,Money,ReceiverID)
其中 ID 唯一标识每一个红包; BatchID 为发红包的批次,一个 BatchID 值可以对应多个 ID 值;SenderID 为发红包人的标识;Money 为红包中的钱数; ReceiverID 记录抢到红包的人的标识。
发红包人一次抛出多个红包,即向红包表中插入多条记录,每条记录表示一个红包, 其 ReceiverID 值为空值。
抢某个红包时,需要判定该红包记录的 ReceiverID 值是否为空,不为空时表示该红包已被抢走,不能再抢,为空时抢红包人将自己的标识写入到 ReceiverID 字段中,即为抢到红包。
【问题 1】 (9分)
引入两个伪指令 a = R(X) 和 W(b,X) 。其中a = R(X) 表示读取当前红包记录的 ReceiverID 字段(记为数据项 X) 到变量 a 中, W(b,X)表示将抢红包人的唯一标识 b 的值写入到当前红包记录的 ReceiverID 字段(数据项 X) 中,变量 a 为空值时才会执行 W(b,X) 操作。假设有多个人同时抢同一红包(即同时对同一记录进行操作),用ai=Ri(X)和Wi(bi,X)表示系统依次响应的第i个人的抢红包操作。假设当前数据项 X 为空值,同时有三个人抢同一红包,则
(1)如下的调度执行序列:
a1=R1,a2=R2(X),W1(b1,X),W2(b2,X),a3=R3(X)
抢到红包的是第几人?并说明理由。
(2)引入共享锁指令 SLocki(X)、独占锁指令XLocki(X)和解锁指令 ULocki(X),其中下标 i表示第 i个抢红包人的指令。如下的调度执行序列:
SLock1(X),a1=R1(X),SLock2(X),a2=R2(X),XLock1(X)......
是否会产生死锁?并说明理由。 (3)为了保证系统第一个响应的抢红包人为最终抢到红包的人,请使用上述。中引入的锁指令,对上述(1)中的调度执行序列进行修改,在满足 2PL协议的前提下,给 出一个不产生死锁的完整的调度执行序列。
下面是用 SQL实现的抢红包程序的一部分,请补全空缺处的代码
CREATE PROCEDURE ScrambleRed (IN BatchNo VARCHAR(20) , --红包批号
(IN RecvrNo VARCHAR(20)) --接收红包者
BEGIN
--是否已抢过此批红包
if exists( SELECT * FROM Red
WHERE BatchID = BatchNo AND ReceiverID = RecvrNo) then
return -1;
end if;
DECLARE NonRecvedNo VARCHAR(30);
DECLARE NonRecvedNo 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 = nonRECVED AND (a)
//执行状态判定
If<修改的记录数>= 1 THEN
COMMIT;
(b);
Return 1;
Else
ROLLBACK;
End if;
(c);
End while
--关闭游标
CLOSE NonRecved RD
Return 0;
END
答案与解析
- 试题难度:较难
- 知识点:事务管理>并发操作设计
- 试题答案:【问题1】(9分)(1)第2人,并发操作出现了丢失更新的问题,第2个的更新覆盖了第1个的更新,原因是破坏了事物的隔离性。
(2)会产生死锁,由于数据X同时被1和2加锁了S锁,在对方没有释放的时候,都无法加成功X锁,导致1和2一直都处于等待的状态。
(3)XLock(X) a=R(X) W(b,X)UNLock(X)
【问题2】(6分)
(a)ReceiverID is NULL
(b)CLOSE NonRecvedRed
(c)FETCH NonRecvedRed INTO NonRecvedNo - 试题解析:【问题1】(1)由于调度出现了丢失更新,第2个事务的更新覆盖了第1个事务的更新,而第3个及以后的,是在第2个更新后再操作,不能更新。所以应该为第2个人抢到红包。
(2)会产生死锁,由于数据X同时被1和2加锁了S锁,在对方没有释放的时候,都无法加成功X锁,导致1和2一直都处于等待的状态,从而产生死锁。
(3)XLock(X) a=R(X) W(b,X)UNLock(X)
【问题2】
(a)由于多人抢红包,可能在写入时,已经被其他人写入了,所以应添加的条件是
ReceiverID is NULL
(b)处后是Return1 语句,也就是直接返回了,不再执行后续的语句,所以(b)处应该执行游标关闭操作即CLOSE NonRecvedRed
(c)在循环中,继续推进游标