阅读下列说明,回答问题1至问题3。
【说明】
某银行的存款业务分为如下三个过程:
(1)读取当前账尸余额,记为R(b):
(2)当前余额b加上新存入的金额x作为新的余额b,即b=b+ x;
(3)将新余额b写入当前账户,记为W(b)。
存款业务分布于该银行各营业厅,并允许多个客户同时向同一账户存款,针对这一需求,完成下述问题。
【问题3】 若用SQL语句编写的存款业务事务程序如下: … START TRANSACTION; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED UPDATE Accounts SET CurrentBalance = CurrentBalance + Amount WHERE AccountID = AccountNo; COMMIT; … 其中:Accounts 为账户表,CurrentBalance 为当前余额,Amount为新存入的金额,AccountNo为外部输入的账户编码。 该事务程序能否正确实现并发的存款业务如果不能,请说明原因,应做怎样的修改 (100字以内) |
参考答案:
解析:不能实现,因为程序中的隔离级别设置为READ UNCOMMITTED,未实现加锁控制,不能达到串行化调度。 修改方法: 将程序中的SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 改为SET TRANSACTION ISOLATION LEVEL SERIALIZABLE。
[分析]: 问题1分析:假设同时有A、B两个客户向同一账号发出存款请求,若A客户将当前余额b=2000加上新存入的金额x=1000存入余额b=3000若B客户将当前余额b=2000加上新存入的金额x=2000存入余额b=4000使得丢失了A客户存入的1000,造成数据不一致。 问题2分析:由于客户要执行的是存款业务,需要在存款业务的伪代码程序“R(b),b=b+x,W(b)”之前加独占锁指令“XLock(b)”,存款业务结束后加解锁指令Unlock(b)。因此,完整的伪代码程序如下:Xlock (b)R (b)b=b + xW (b)Unlock (b) 问题3分析:隔离级别定义了事务与事务之间的隔离程度。隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差;隔离程度越低,数据库的并发性越好。ANSI/ISO SQL92 标准定义了一些数据库操作的隔离级别: 未提交读(READ UNCOMMITTED) 提交读(READ COMMITTED) 重复读(REPEATABLE READ) 序列化(SERIALIZABLE) 问题3事务程序不能正确实现并发的存款业务其原因是语句SET TRANSACTION ISOLATION LEVEL的隔离级别设置的是READ UNCOMMITTED,没有实现加锁控制,为此应该将隔离级别设置为SERIALIZABLE。