《数据库实验报告四(共10页).doc》由会员分享,可在线阅读,更多相关《数据库实验报告四(共10页).doc(10页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上数据库原理实验报告实验七: 事务与并发控制学号姓名班级日期杨添文2015.11.14实验七:事务与并发控制 一、 实验内容 假设学校允许学生将银行卡和校园卡进行绑定,在student数据库中有如下的基本表,其中校园卡编号cardid即为学生的学号: icbc_card(studcardid,icbcid,balance) /校园卡ID,工行卡ID,银行卡余额 campus_card(studcardid,balance) /校园卡ID,校园卡余额针对以上数据库按照要求完成下列实验:1. 编写一个事务处理(begin tran)实现如下的操作:某学号为的学生要从银行卡中
2、转账200元到校园卡中,若中间出现故障则进行rollback。(15分)(1) 程序代码如下:declare balance intselect balance=balance-200from icbc_cardwhere studcardid=update icbc_cardset balance=balancewhere studcardid=update campus_cardset balance=balance+200where studcardid=if balance0rollbackcommit;(2)结果如下:(结果很明显,阴影部分即显示操作已成功。)2. 针对本题的数据库和
3、表,分别用具体的例子展现四种数据不一致问题:丢失修改、读脏数据、不可重复读和幻读(删除和插入)。(40分,每种数据不一致10分)(1) 丢失修改:代码如下:set tran isolation level read uncommitteddeclare balance intselect balance=balancefrom icbc_cardwhere studcardid=waitfor delay 00:00:10update icbc_cardset balance=balance-300where studcardid=select balancefrom icbc_cardwhe
4、re studcardid=这段代码执行的时间设置为10秒,在此期间,重复执行这段代码(可以增加一个窗口,在10秒内执行),结果如下截图:很明显,若是成功修改,balance中的数据就会是400,而不是700。(2) 读脏数据:代码如下:(两个事务的执行时间间隔不超过10秒) 1、先编写代码执行事务1(执行一次对balance的操作,回滚)set tran isolation level read uncommittedbegin tranupdate icbc_cardset balance=balance+2000where studcardid=select balancefrom ic
5、bc_cardwhere studcardid=waitfor delay00:00:10rollback;select balancefrom icbc_cardwhere studcardid=这段代码的结果为:(balance的值已经返回正常值,为1000)2、执行事务2:set tran isolation level read uncommittedselect balancefrom icbc_cardwhere studcardid=这段代码结果为:(结果不是1000,却是3000,说明读了脏数据)(3) 不可重复读:代码段为:(两个事务的执行时间间隔不超过10秒)1、 先执行事
6、务1:declare balance int/*第一次读数据*/select balance=balancefrom icbc_cardwhere studcardid=print balancewaitfor delay 00:00:10/*第二次读数据*/select balance=balancefrom icbc_cardwhere studcardid=print balance结果为:(可以很明显的看出来,两次读数据的结果不一致,原因在于事务2的中间加入,而事务1又没有加锁导致)2、 再执行事务2:(在第二次读数据之前更新)update icbc_cardset balance=b
7、alance*2where studcardid= 结果:(4) 幻读:代码段为:(两个事务的执行时间间隔不超过10秒)1、 先执行事务1:select balancefrom icbc_cardwhere studcardid=waitfor delay 00:00:10select balancefrom icbc_cardwhere studcardid=结果:(因为增加了一条数据,两次读的结果就不一致)2、 再执行事务2:(增加一条数据)insert into icbc_cardvalues(,2000)结果: 3. 利用锁机制、数据库的隔离级别等,设计方案分别解决上述丢失修改、读脏数
8、据和不可重复读(或者幻读)的数据不一致问题。(30分,每种数据不一致10分,提示可以用sp_lock系统存储过程查看当前锁状况)(1) 丢失修改:事务1:(对表的操作加锁)-set tran isolation level read uncommittedbegin trandeclare balance intselect * from icbc_card with(tablockx)select balance=balancefrom icbc_cardwhere studcardid=waitfor delay 00:00:10update icbc_cardset balance=ba
9、lance-300where studcardid=select balancefrom icbc_cardwhere studcardid=commit事务2与上述一致,间隔10秒,结果为:(可知没有丢失修改,事务1结果为800,而事务2结果为500)事务1:事务2:(2) 读脏数据:1、 事务1:set tran isolation level read committedbegin tranupdate icbc_cardset balance=balance+2000where studcardid=select balancefrom icbc_cardwhere studcardi
10、d=waitfor delay00:00:10rollback;select balancefrom icbc_cardwhere studcardid=2、 事务2:set tran isolation level read committedselect balancefrom icbc_cardwhere studcardid=3、 结果:(事务2 数据已经正常)(1) 事务1:(2) 事务2:(3) 不可重复读:1、 事务1:begin transelect * from icbc_card with (tablockx)declare balance int/*第一次读数据*/sel
11、ect balance=balancefrom icbc_cardwhere studcardid=print balancewaitfor delay 00:00:10/*第二次读数据*/select balance=balancefrom icbc_cardwhere studcardid=print balancecommit2、 事务2:set tran isolation level read committedupdate icbc_cardset balance=balance*2where studcardid=3、 结果:(可以明显看出可以重复读数据)事务1:事务2:4. 构
12、造一个出现死锁的情形。(10分)(1) 事务1: begin tran update campus_card with(xlock) set balance = balance + 100 waitfor delay 00:00:10 select * from icbc_card with(holdlock) rollback tran(2) 事务2: begin tran update icbc_card with(xlock) set balance = balance + 200 waitfor delay 00:00:10 select * from campus_card with(holdlock) rollback tran(3)结果为:事务2有结果,执行成功:事务1执行时出现死锁: 5. 利用dbcc log命令查看student数据库的事务日志。(5分)SQL语句:dbcc log(student,4)结果:二、 实验反思 事务在执行过程中,由于并行的执行特点,经常会因为数据共享而产生数据的各种误操作,例如读脏数据等等,这时候就需要利用到锁机制来平衡这个短板,本节课的内容就是基于这个问题而提出的,实验本身难度不大,在于细心。专心-专注-专业