当前位置:文档之家› 数据库实验报告记录7

数据库实验报告记录7

数据库实验报告记录7
————————————————————————————————作者:————————————————————————————————日期:
《数据库原理》实验报告
题目:实验七事务与并发控制学号姓名班级日期Xxxx Xx Xxx 2016.11.10
一. 实验内容、步骤以及结果
假设学校允许学生将银行卡和校园卡进行绑定,在 student 数据库中有如下的基本表,其中校园卡编号 cardid 即为学生的学号: icbc_card(studcardid,icbcid,balance) //校园卡 ID,工行卡 ID,银行卡余额 campus_card(studcardid,balance) //校园卡 ID,校园卡余额数据创建的代码:
1.编写一个事务处理(begin tran)实现如下的操作:某学号为20150032的学生要从银
行卡中转账200元到校园卡中,若中间出现故障则进行rollback。

(15分)
修改后的结果:
2.针对本题的数据库和表,分别用具体的例子展现四种数据不一致问题:丢失修改、
读脏数据、不可重复读和幻读(删除和插入)。

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

最终【事务 2】的结果 50 覆盖了【事务 1】的更改值,结果不是期望值 40
读脏数据
--事务一:
begin tran
declare @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--回滚
go
select balance from campus_card where studcardid='20150032'
--事务二:
begin tran
declare @balance decimal(10,2)
select @balance=balance from campus_card
where studcardid='20150032'
update campus_card
set balance=@balance+50 where studcardid='20150032'
commit tran
go
select balance from campus_card where studcardid='20150032'
【事务1】原数据为50,更改了数据+100,【事务2】读取了表中更改后的值再进行操作,【事务1】回滚。

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

不可重复读
--事务一:
begin tran
select balance from campus_card where studcardid='20150031'
waitfor delay'00:00:05'
select balance from campus_card where studcardid='20150031'
commit tran
--事务二:
begin tran
update campus_card set balance=balance+200
where studcardid='20150031'
commit tran
select balance from campus_card where studcardid='20150031'
事务二对数据的改变影响了事物一两次读取数据的值,使读取数据产生错误
幻读
➢插入
--事务一:
begin tran
select balance from campus_card where studcardid='20150031'
waitfor delay'00:00:05'
select balance from campus_card where studcardid='20150031'
commit tran
--事务二:
begin tran
insert into campus_card values('20150031', 30)
commit tran
➢删除
--事务一:
begin tran
select balance from campus_card where studcardid='20150031'
waitfor delay'00:00:05'
select balance from campus_card where studcardid='20150031'
commit tran
--事务二:
begin tran
delete from campus_card where studcardid='20150031'
commit tran
3.利用锁机制、数据库的隔离级别等,设计方案分别解决上述丢失修改、读脏数据和
不可重复读(或者幻读)的数据不一致问题。

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

(10分)
set tran isolation level read committed
--事务 1
begin tran
declare @read int select @read=grade from sc
where sno='95003'
waitfor delay'00:00:10'
update sc set grade=@read-1 where sno='95003'
--事务 2
begin tran
declare @read1 int select @read=grade from sc
where sno='95003'
update sc set grade=@read1-1 where sno='95003'
5.利用dbcc log命令查看student数据库的事务日志。

(5分)
dbcc log('student', type=2)
二. 实验中出现的问题以及解决方案(对于未解决问题请将问题列出来)
除了标题内容以外,该部分内容中还可以写对于实验的一些感受,建议,意见等。

对于构造事物的并发进程比较困难,实验中为了构造并发执行的控制,采用waitfor delay'00:00:05' ,使得一个事物的进程等待5s,然后执行另外一个事物进程,这样就形成了并发事物,便于实施构造数据不一致和死锁现象。

相关主题