阅读下列说明,回答问题1至问题3,将解答填入答题纸的对应栏内。【说明】 某航空售票系统负责所有本地起飞航班的机票销售,并设有多个机票销售网点。以下为E一SQL编写的部分售票代码: EXEC soL SELECT balance INTO:x FROM tickets WHERE flight=:flightno; printf(”航班%s当前剩余机票数为:%d\n请输入购票数:", flightno,x); scanf("%d", &a); EXEC soL UPDATE tickets SET balance =x =:a WHERE flight=:flightno; 请根据上述描述,完成下列问题。
问答题 上述售票程序,在并发状态下,可能发生什么错误?产生这种错误的原因是什么?
【正确答案】正确答案:当两个用户同时购买同一航班的机票时,可能发生丢失修改的错误,即一个用户购票后对剩余票数的修改被另一个用户的修改覆盖,第一个用户的修改并未体现到数据库中。产生错误的原因是并发操作破坏了事务的隔离性。
【答案解析】解析:本题考查事务基本概念及编程应用。 此类题目要求考生认真阅读题目对实际问题的描述,分析现实业务中存在的问题,并以事务的方式提出解决方案及编程中的处理方式。 根据题目描述的售票程序及部分代码,程序的逻辑是正确的,但在并发状态下,可能会产生错误。修改指令UPDATE会被分解为读取剩余票数到变量、修改变量、写入数据库几个步骤,并发时存在指令交叉,造成一个程序的修改被其他程序所覆盖,称为丢失修改错误。如下面所示的一个并发调度:
问答题 若将上述代码封装成一个完整的事务,则:(1)在并发请求下的响应效率会存在什么问题?(2)分析产生效率问题的原因。(3)给出解决方案。
【正确答案】正确答案:(1)在并发请求下,查询剩余票数后,会等待用户的响应,此时数据被锁定无法修改,导致其他用户只能等待该用户购票结束后才可购票,降低了系统的并发度。 (2)产生效率问题的原因是事务划分不合理。 (3)应将查询剩余票数的指令置于事务外部,事务只负责用户购票。
【答案解析】解析:封装的事务由两条SQL语句构成,中间存在与用户的交互,等待用户输入购票张数,会造成长事务,加锁状态下,其他购票事务程序会长时间等待,严重影响系统的响应速度。应将查询票数从事务中分离出来,UPDATE指令独立构成一个事务。
问答题 下面是改写的存储过程,其中flightno为航班号;a为购票数;result为执行状态:1表示成功,0表示失败;表tickets中的剩余机票数balance具有大于等于零约束。请补充完整。 CREATE PROCEDRUE buy_ticket(char[]flightno IN,(a), int result OUT)AS BEGIN UPDATE tickets SET balance=(b); WHERE flight=flightno; if csoLcode<>SUCCESS){ //soLcode为SQL语句的执行状态(c); result=0; return; } COMMIT;(d)END
【正确答案】正确答案:1.int a IN 2.balance一a 3.ROLLBACK(或ROLLBACKWORK) 4.result=1;retum。
【答案解析】解析:这是一个用存储过程实现购票的事务程序,存储过程参数部分给出了航班号和执行状态返回参数,应加入购票张数作为参数;修改剩余票数的UPDATE语句处需补充的是当前票数减去购票张数;SQL语句执行错误时应该进行事务回滚并退出程序,所有事务代码执行完成后提交,并返回。