数据库实验报告事务与并发控制文档格式.docx
《数据库实验报告事务与并发控制文档格式.docx》由会员分享,可在线阅读,更多相关《数据库实验报告事务与并发控制文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
1.掌握事务机制,学会创建事务。
2.理解事务并发操作所可能导致的数据不一致性问题,用实验展现四种数据不一致性问题:
丢失修改、读脏数据、不可重复读以及幻读现象。
3.理解锁机制,学会采用锁与事务隔离级别解决数据不一致的问题。
4.了解数据库的事务日志。
1.2.实验内容
假设学校允许学生将银行卡和校园卡进行绑定,在student数据库中有如下的基本表,其中校园卡编号cardid即为学生的学号:
icbc_card(studcardid,icbcid,balance)//校园卡ID,工行卡ID,银行卡余额
campus_card(studcardid,balance)//校园卡ID,校园卡余额
数据创建的代码:
usestudent
createtablecampus_card
(studcardidChar(8),
balanceDecimal(10,2))
createtableicbc_card
(
studcardidChar(8),
icbcidChar(10),
balanceDecimal(10,2)
)
insertintocampus_cardvalues('
20150031'
30)
20150032'
50)
20150033'
70)
insertintoicbc_cardvalues('
'
2015003101'
1000)
2015003201'
2015003301'
针对以上数据库按照要求完成下列实验:
1.编写一个事务处理(begintran)实现如下的操作:
某学号为20150032的学生要从银行卡中转账200元到校园卡中,若中间出现故障则进行rollback。
(15分)
settransactionisolationlevel
repeatableread
begintransaction
usestudent
go
declare@xdecimal(10,2)
select@x=balance
fromicbc_card
wherestudcardid='
set@x=@x-200
if(@x>
=0)
begin
updateicbc_cardsetbalance=@xwherestudcardid='
updatecampus_cardsetbalance=balance+200wherestudcardid='
committran
end
else
print'
余额不足,不能转账'
rollbacktran
2.针对本题的数据库和表,分别用具体的例子展现四种数据不一致问题:
丢失修改、读脏数据、不可重复读和幻读(删除和插入)。
(40分,每种数据不一致10分)
(1).丢失修改
--事务1
begintran
declare@balancedecimal(10,2)
select@balance=balancefromcampus_cardwherestudcardid='
waitfordelay'
00:
05'
set@balance=@balance-10
updatecampus_cardsetbalance=@balancewherestudcardid='
committran
selectbalancefromcampus_cardwherestudcardid='
--事务2
declare@balance1decimal(10,2)
select@balance1=balancefromcampus_cardwherestudcardid='
set@balance1=@balance1-20
updatecampus_cardsetbalance=@balance1wherestudcardid='
selectbalancefromcampus_cardwherestudca
【事务1】更改了数据,结果为60,但是没有被读到。
最终【事务2】的结果50覆盖了【事务1】的更改值,结果不是期望值40
(2).读脏数据
--事务1
SETTRANSACTIONISOLATIONLEVELREADUNCOMMITTED
--READUNCOMMITTED执行脏读,不发出共享锁,也不接受排他锁
begintran
declare@balancedecimal(10,2)
select@balance=balancefromcampus_cardwherestudcardid='
updatecampus_cardsetbalance=@balance+100wherestudcardid='
waitfordelay'
rollbacktran--回滚
--事务2
updatecampus_cardsetbalance=@balance+50wherestudcardid='
committran
【事务1】更改了数据,【事务2】读取了表中更改后的值再进行操作,【事务1】回滚。
最终的表存储了错误结果。
(3)不可重复读
--事务1
SETTRANSACTIONISOLATIONLEVELREADCOMMITTED
selectbalancefromcampus_cardwherestudcardid='
waitfordelay'
selectbalancefromcampus_cardwherestudcardid='
【事务1】读取了数据,【事务2】更改数据,【事务1】再读取数据。
【事务1】两次读取都不一样!
(4).幻读
插入
selectbalancefromcampus_cardwherestudcardid='
SETTRANSACTIONISOLATIONLEVELSERIALIZABLE
insertintocampus_cardvalues('
30)
删除
settranisolationlevelrepeatableread
deletefromcampus_cardwherestudcardid='
3.利用锁机制、数据库的隔离级别等,设计方案分别解决上述丢失修改、读脏数据和不可重复读(或者幻读)的数据不一致问题。
(30分,每种数据不一致10分,提示可以用sp_lock系统存储过程查看当前锁状况)
修改隔离级别以却确定数据的正确性:
丢失修改,在SQL语句前加未提交读:
settranisolationlevelreaduncommitted
读脏数据,在SQL语句前已提交读:
settranisolationlevelreadcommitted
不可重复读,在SQL语句前可重复读:
settranisolationlevelrepeatableread
幻读在SQL语句前加可串行读:
settranisolationlevelserializable
4.构造一个出现死锁的情形。
(10分)
首先将锁的级别改为提交可读
declare@readint
select@read=grade
fromsc
wheresno='
95003'
10'
updatesc
setgrade=@read-1
5.利用dbcclog命令查看student数据库的事务日志。
(5分)
DBCClog('
student'
TYPE=2)