【数据库】sql server 2012数据库基础-并发控制-实验报告

    这是大三第一学期《数据库基础》的实验报告,总共15个实验,前12个百度文库都有,后面三个网上找不到都是我自己花了很多时间琢磨出来的,希望对大家,以及将来的我有所帮助!

实验13用户管理及权限管理  点我查看

实验14并发控制   本文

实验15数据恢复   点我查看

课程名称   数据库基础            

实验项目   实验14 并发控制       

1.实验目的:

理解和体会事务、封锁、死锁和并发控制等内容,加强对DBMS功能的认识。

2.实验内容:

事务、封锁、死锁和并发控制

3.实验要求:

  1. 独立完成本实验,以多个用户身份登录,创建管理多个事务。
  2. 设计一组操作产生“脏”读问题,然后通过封锁避免“脏”读问题。
  3. 设计一组操作产生不可重复读问题,然后通过封锁避免不可重复读问题。
  4. 设计一组操作产生丢失更新问题,然后通过封锁避免丢失更新问题。
  5. 设计一组产生死锁的操作,再利用相同顺序法有效的避免死锁。
  6. 在实验报告中要给出具体的操作步骤和过程,并针对各种情况做出具体的分析和讨论,很好的体会事务的性质和并发控制的作用。

4.实验准备 

(1) 查询一个已经被其他事务更新、但尚未提交的元组,将会引起“脏”读问题;为避免该问题应该实施共享封锁。

(2) 为避免不可重复读问题,应该将共享封锁保持到事务结束。

(3) 为避免丢失更新问题,应该实施独占封锁或更新封锁。

(4) SQL Server的封锁操作是在相关语句的“WITH(<TABLE_HINT>)”子句中完成的。

(5) 设置隔离级别的命令是:

SET TRANSACTION ISOLATION LEVEL

{READ COMMITTED

|READ UNCOMMITTED

|REPEATABLE READ

|SERIALIZABLE}

5.实验过程(含代码、实验过程、遇到的问题和解决方法等):

 

第一题:设计一组操作产生“脏”读问题,然后通过封锁避免“脏”读问题。

 

1.1概念:我个人觉得脏读就是A事务读到了B事务未提交的数据。(A事务修改数据1后,B事务读取了当前的数据1,然后A因为某种错误回档,导致B事务读取的数据错误)。通俗来说就是A事务放了B事务的鸽子。

1.2整体思路:

先运行一个事务A (  1.修改课程学时数据为8 ; 2.等待20秒 ; 3.回滚数据,学时还原为6 ),在事务A的第二步等待的时候,运行事务B (  1.查询学时; 2. 等待20秒; 3. 查询学时)。其中事务B第一次查询是事务A中间的等待期,所以学时为8,第二次查询在事务A结束后,所以学时为6.

1.3 代码截图:

首先我们在第一个查询页面运行以下代码:

图 1  查询窗口1  先更新学时为‘8 ’ 后回滚

 

代码解析:

以上第一行代码为:事务zwz1的开始标志

第二行代码:更新课程表中课程编号为1128的学时为8

第三行代码:等待20秒延迟

第四行代码:回滚第二行代码,恢复到该事务未执行的状态

第五行代码:查询课程表中课程编号为1128的所有信息

 

接下来在查询窗口2,执行以下代码:

图 2  查询窗口2  分别在事务A 等待期 和 结束后 查询学时

 

代码解析:

以上第一行代码为:在无锁的情况下查询课程表中课程编号为1128的所有信息(为错误信息)

第二行代码:等待20秒的时间

第三行代码:再次查询,发现数据不一致(本次为正确信息)

 

接下来是加封锁的情况:

图 3  加了写读锁后(不加也一样),窗口1回滚后 学时还是6 不变

 

注:和前面不加封锁对比,多了第一行代码,即加上一个“写读锁”,个人理解为“当事务A想读取某数据,必须要等当前其他事务修改完,才能读

 

图 4  加了写读锁之后 事务B等事务A全部执行完毕后再执行 所以结果都是6

 

注:窗口二和前面不加封锁相比,也是多了第一行代码,运行的时候能明显感觉到运行了40秒,即等窗口1执行完毕后再执行窗口2的事务。

 

 

第二题:设计一组操作产生不可重复读问题,然后通过封锁避免不可重复读问题。

2.1 概念:事务A读某数据后,事务B将其修改,然后事务A再次读数据和之前的不一样。通俗理解为被调包。

2.2 总体思路:事务A读取1128号课程数据后,等待5秒,然后事务A再次读取该课程数据。其中事务B利用事务A的等待期,对该课程数据进行修改。

2.3代码截图:

图 5 事务A三部曲:读取数据 ;等待期 ; 读取数据 。发现数据不一致

 

图 6  事务B 在事务A等待期内 对数据进行修改

 

 

解决方案:设置隔离级别 :repeatable read(可重复读)  书本179页

 

思路:在原有基础上 增加封锁

 

图 7 事务A执行过程中 事务B无法插入 所以前后查询结果一致

 

图 8  事务B只能在事务A执行完毕后再执行 修改成功

 

图 9  事务B执行后 学时数据被修改

 

 

第三题:设计一组操作产生丢失更新问题,然后通过封锁避免丢失更新问题。

 

3.1概念:丢失更新我个人理解为事务A和事务B同时对该数据进行修改,假设事务A执行时间短,事务B执行时间长,那么事务B会覆盖事务A的修改结果。(换一种方式的放鸽子)

 

但是在SQL Server 2012中,不管是同一用户还是不同用户,都自带锁,即都是在先执行的事务执行完毕后,再执行另一个事务。

 

 

3.2总体思路 :

 

事务A先对学时数据查询(原先为6)再对学时进行修改(修改为8)最后5秒等待期再次查询(结果为8)

 

事务B在事务A的等待期内开始执行(结果是等事务A结束再执行的),也先对学时数据查询(原先为6)再对学时进行修改(修改为10)最后5秒等待期再次查询(结果为10)

 

结果为事务B覆盖了事务A的更新,可我觉得这只是因为事务B比事务A晚执行的原因

 

 

3.3 代码截图:

 

图 10 刚开始 学时数据为 6

 

先执行事务A,紧接着执行事务B(相当于在事务A的等待期内执行)

图 11 可以视为 同时执行事务A和事务B

 

观察事务A 、事务B的执行结果:

 

图 12 事务A执行前数据为6  执行后数据为8

 

图 13 事务B执行前数据为8  执行后数据为10 说明和事务A互不干扰

 

这时候我们可以发现,事务B在事务A全部完成之后再执行,对事务A互不干扰 ,最后查看数据库中的数据为10.

图 14 数据库 课程表中的数据

 

 

第四题:设计一组产生死锁的操作,再利用相同顺序法有效的避免死锁。

 

4.1 概念 :就是你等我,我等你,导致互相一直等下去,卡死循环

 

4.2整体思路:

同样 sql server 2012也自带对死锁的预防,实验如下:

 

我先执行查询1(操作1,等待5秒,操作2),然后马上执行查询2(操作2,等待5秒,操作1),因为执行中间有五秒等待时间,查询1的第二个更新等待查询2执行完毕,查询2的第二个更新等待查询1执行完毕,构成死锁。

 

不过大概10秒钟之后,sql server 2012自动解开了死锁,即查询2做出让步,查询1全部执行。( &^^^& 太智能了)

 

 

4.3代码截图:

图 15 事务A被事务B让步 成功执行

 

图 16  事务B为了让步事务A,成为牺牲品,后半段执行失败

 

 

然后使用相同顺序法调换顺序之后:

 

图 17  事务A正常执行

 

图 18 事务B正常执行

即没有死循环,正常运行。

 

6.实验总结:

本次实验学习了并发控制,目的是通过实验了解四种异常事务状态(分别是脏读、不可重复读、丢失更新、死锁),理解发生异常事务状态的原理,以及我们要则么通过增加事务隔离级别来封锁,实现并发控制。当然随着事务隔离级别提升,所消耗的资源也变多,所以要根据实际情况选择隔离级别,也要预防死锁现象的发生。

当然sql server 2012版本自带预防机制,所以导致部分实验没法做,但我觉得我们要学的重点是理解异常产生的原理,以及如何防止异常的发生。

发布了42 篇原创文章 · 获赞 26 · 访问量 9580

猜你喜欢

转载自blog.csdn.net/qq_41464123/article/details/104064983