当前位置:文档之家› 数据库实验报告:事务与并发控制

数据库实验报告:事务与并发控制

1.实验七:事务与并发控制1.1.实验目的1.掌握事务机制,学会创建事务。

2.理解事务并发操作所可能导致的数据不一致性问题,用实验展现四种数据不一致性问题:丢失修改、读脏数据、不可重复读以及幻读现象。

3.理解锁机制,学会采用锁与事务隔离级别解决数据不一致的问题。

4.了解数据库的事务日志。

1.2.实验内容假设学校允许学生将银行卡和校园卡进行绑定,在student数据库中有如下的基本表,其中校园卡编号cardid即为学生的学号:icbc_card(studcardid,icbcid,balance) //校园卡ID,工行卡ID,银行卡余额campus_card(studcardid,balance) //校园卡ID,校园卡余额数据创建的代码:use studentcreate table campus_card(studcardid Char(8) ,balance Decimal(10,2))create table icbc_card(studcardid Char(8),icbcid Char(10),balance Decimal(10,2))insert into campus_card values('20150031', 30)insert into campus_card values('20150032', 50)insert into campus_card values('20150033', 70)insert into icbc_card values('20150031','2015003101', 1000)insert into icbc_card values('20150032','2015003201', 1000)insert into icbc_card values('20150033','2015003301', 1000)针对以上数据库按照要求完成下列实验:1.编写一个事务处理(begin tran)实现如下的操作:某学号为20150032的学生要从银行卡中转账200元到校园卡中,若中间出现故障则进行rollback。

(15分)set transaction isolation levelrepeatable readbegin transactionuse studentgodeclare@x decimal(10, 2)select@x=balancefrom icbc_cardwhere studcardid='20150032'set@x=@x-200if(@x>=0)beginupdate icbc_card set balance=@x where studcardid='20150032'update campus_card set balance=balance+200 where studcardid='20150032'commit tranendelsebeginprint'余额不足,不能转账'rollback tranend2.针对本题的数据库和表,分别用具体的例子展现四种数据不一致问题:丢失修改、读脏数据、不可重复读和幻读(删除和插入)。

(40分,每种数据不一致10分)(1).丢失修改--事务1begin trandeclare@balance decimal(10,2)select@balance=balance from campus_card where studcardid='20150033'waitfor delay'00:00:05'set@balance=@balance-10update campus_card set balance=@balance where studcardid='20150033'commit trangoselect balance from campus_card where studcardid='20150033'--事务2begin trandeclare@balance1decimal(10,2)select@balance1=balance from campus_card where studcardid='20150033'waitfor delay'00:00:05'set@balance1=@balance1-20update campus_card set balance=@balance1where studcardid='20150033'commit trangoselect balance from campus_card where studca【事务1】更改了数据,结果为60,但是没有被读到。

最终【事务2】的结果50覆盖了【事务1】的更改值,结果不是期望值40(2).读脏数据--事务1SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED--READ UNCOMMITTED 执行脏读,不发出共享锁,也不接受排他锁begin trandeclare@balance decimal(10,2)select@balance=balance from campus_card where studcardid='20150032'update campus_card set balance=@balance+100 where studcardid='20150032' waitfor delay'00:00:05'rollback tran--回滚goselect balance from campus_card where studcardid='20150032'--事务2SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDbegin trandeclare@balance decimal(10,2)select@balance=balance from campus_card where studcardid='20150032'update campus_card set balance=@balance+50 where studcardid='20150032' commit trangoselect balance from campus_card where studcardid='20150032'【事务1】更改了数据,【事务2】读取了表中更改后的值再进行操作,【事务1】回滚。

最终的表存储了错误结果。

(3)不可重复读--事务1SET TRANSACTION ISOLATION LEVEL READ COMMITTEDbegin transelect balance from campus_card where studcardid='20150031'waitfor delay'00:00:05'select balance from campus_card where studcardid='20150031'commit tran--事务2SET TRANSACTION ISOLATION LEVEL READ COMMITTEDbegin tranupdate campus_card set balance=balance+200 where studcardid='20150031' commit tran【事务1】读取了数据,【事务2】更改数据,【事务1】再读取数据。

【事务1】两次读取都不一样!(4).幻读插入--事务1SET TRANSACTION ISOLATION LEVEL READ COMMITTEDbegin transelect balance from campus_card where studcardid='20150031'waitfor delay'00:00:05'select balance from campus_card where studcardid='20150031' commit tran--事务2SET TRANSACTION ISOLATION LEVEL SERIALIZABLEbegin traninsert into campus_card values('20150031', 30)commit tran删除--事务1SET TRANSACTION ISOLATION LEVEL READ COMMITTEDbegin transelect balance from campus_card where studcardid='20150031'waitfor delay'00:00:05'select balance from campus_card where studcardid='20150031'commit tran--事务2set tran isolation level repeatable readbegin trandelete from campus_card where studcardid='20150031'commit tran3.利用锁机制、数据库的隔离级别等,设计方案分别解决上述丢失修改、读脏数据和不可重复读(或者幻读)的数据不一致问题。

(30分,每种数据不一致10分,提示可以用sp_lock系统存储过程查看当前锁状况)修改隔离级别以却确定数据的正确性:丢失修改,在SQL语句前加未提交读:set tran isolation level read uncommitted读脏数据,在SQL语句前已提交读:set tran isolation level read committed不可重复读,在SQL语句前可重复读:set tran isolation level repeatable read幻读在SQL语句前加可串行读:set tran isolation level serializable4.构造一个出现死锁的情形。

相关主题