数据库第五次实验报告Word下载.docx
《数据库第五次实验报告Word下载.docx》由会员分享,可在线阅读,更多相关《数据库第五次实验报告Word下载.docx(16页珍藏版)》请在冰豆网上搜索。
insertintosalesvalues('
A0001'
0)
createproceduremodi_aas
declare@iint
declare@s1int
settransactionisolationlevelreadcommitted
select@i=1
while(@i<
=2000)begin
begintran
select@s1=数量fromsaleswhere客户代号='
waitfordelay'
00:
00.002'
updatesalesset数量=@s1+1where客户代号='
committran
select@i=@i+1
end
createproceduremodi_mas
declare@iint
updatesalesset数量=@s1-1where客户代号='
同时运行存储过程modi_a和modi_m可以看到如下结果:
本应该数量一栏应该是0的,说明数据发生了丢失数据。
将两个存储过程中事务中select语句改为:
select@s1=数量fromsaleswith(tablockx)where客户代号=’A0001’
然后再次同时运行两个存储过程,结果如下:
可以看到如果在存储过程中对数据加上独立锁后数量结果始终为0。
2、脏读数据
createproceduredirt_wrollas
settransactionisolationlevelreaduncommitted
=16000)begin
begintran
rollbacktran
00.000'
createproceduredirt_ras
=60000)begin
if(@s1<
>
1000)raiserror('
发生了脏读!
'
16,1)
并行运行上面两个存储过程dirt_wroll和dirt_r看到如下结果:
可知如果是这样的话,就会发生脏读的现象。
如果把上述的存储过程中的设置隔离级别的语句
“settransactionisolationlevelreaduncommitted”
改为:
“settransactionisolationlevelreadcommitted”
则就可以把问题解决了。
3、不可重复读
createprocedurerep_ras
declare@s1int
declare@s2int
=3000)begin
00.001'
select@s2=数量fromsaleswhere客户代号='
@s2)raiserror('
发生不可重复读!
createprocedurerep_was
=1000)begin
以上两个存储过程同时运行的时候,会出现不可重复的现象,结果如下:
预防这种结果的方法就是制定更高的事务隔离级别,如:
repeatableread、snapshot、serializable.
4、幻影问题
createprocedurehuany_Ias
settransactionisolationlevelrepeatableread
deletefromsaleswhere(客户代号='
A1111'
)
=1000)begin
insertintosales(客户代号,数量)values('
1000)
createprocedurehuany_uas
declare@jint
=300)begin
updatesalesset数量=数量+3where客户代号='
select@j=0
select@j=count(*)fromsaleswhere客户代号='
and数量=1000
if(@j>
0)raiserror('
发生了幻影现象!
同时运行上面两个存储过程huany_I和huany_u会出现幻影现象,结果如下图:
解决的方法为:
指定事务级别为serializable。
5、抢答问题
createprocedureqiangxian1as
=5000)begin
begintran
updatesaleset数量=数量+10000where客户代号=@i
if(@@error<
0)rollbacktran
elsecommittranselect@i=@i+1
end
当同时执行像上面多个存储过程的时候就会出现抢答现象,记录的修改只能由先加锁的进程完成。
6、编号产生问题
createprocedurebhscas
declare@s1int
=1500)begin
select@s1=max(客户代号)+1fromsale
insertintosale(客户代号,数量)values(@s1,@i)
committran
select@i=@i+1
多个以上的存储过程并行运行会出现编号重复现象,而且发现重复程度与并发程度成正比。
解决的办法法有:
(1)设计编号产生事务一开始就加独立锁;
(2)设计编号产生事务,其中采用插入后即查询重复编号情况,若发现重复,能进行反复尝试再插入;
(3)利用一般数据库具有的identity字段来保障编号的唯一性。
下面的存储过程体现了前两种方法,当多个此存储过程同时运行时不会在发生编号重复现象。
createprocedurebhsc2as
declare@kkint
selecttransactionlevelreadcommitted
=1500)begin
begintran
select@s1=max(客户代号)+1fromsalewith(tablock)
select@kk=count(*)fromsalewhere客户代号=@1
if@kk>
=2beginrollbacktrancontinueend
elsecommittran
7、手工加锁下并发事务读写冲突
createprocedurepminas
settransactionisolationlevelreadcommitted
while(@i<
=500)begin
select@s1=数量fromsaleswith(updlock)where客户代号='
00.003'
if(@@error<
elsecommittran
select@i=@i+1;
createprocedurepaddas
实验二:
数据库备份与恢复
(1)备份数据库
创建用于存放jxgl数据库完整备份的逻辑备份设备,然后备份整个jxgl数据库
usemaster
execsp_addumpdevice'
disk'
'
jxgl_1'
C:
\ProgramFiles\MicrosoftSQLServer\MSSQL.1\MSSQL\Backup\jxgl_1.dat'
backupdatabaseJXGLtojxgl_1
创建一个数据库和日志的完整备份。
将数据库备份到称为jxgl_1的逻辑备份设备上,然后将日志备份到称为jxglLog1的逻辑备份设备上:
jxglLog1'
\ProgramFiles\MicrosoftSQLServer\MSSQL.1\MSSQL\Backup\jxglLog1.dat'
backuplogjxgltojxglLog1;
创建一个文件备份:
backupdatabase[JXGL]file='
JXGl'
todisk=
\ProgramFiles\MicrosoftSQLServer\MSSQL.1\MSSQL\Backup\jxglBackUp.bak'
withinit,
nounload,name='
jxglBackUp'
noskip,stats=10,noformat
backuplogJXGLtojxgl_1withnorecovery;
(2)还原数据库
从还原设备jxgl_1还原完整数据库:
restoredatabaseJXGLfromjxgl_1
还原完整数据库备份后还原差异备份,差异备份追加到包含完整数据库备份的备份设备上。
restoredatabasejxglfromjxgl_1withnorecovery
restoredatabasejxglfromjxgl_1withfile=2
使用restart选项重新启动因服务器电源故障而中断的restore操作:
restoredatabasejxglfromjxgl_1
restoredatabasejxglfromjxgl_1withrestart
还原完整数据库和事务日志,并将已还原的数据库移动到C:
\ProgramFiles\MicrosoftSQLServer\MSSQL\Data目录下:
restoredatabasejxglfromjxgl_1withnorecovery,move'
jxgl'
to
\ProgramFiles\MicrosoftSQLServer\MSSQL\Data\Newjxgl.mdf'
move'
jxgl_Log'
to
\ProgramFiles\MicrosoftSQLServer\MSSQL\Data\Newjxgl.1df'
restorelogjxglfromjxglLog1withrecovery
从一个文件备份中还原:
restoredatabase[jxgl]file=N'
fromDISK=N'
f:
\ProgramFiles\MicrosoftSQLServer\MSSQL\backup\jxgl备份.bak'
(3)对数据库jxgl的备份与还原操作
<
1>
将jxgl数据库的故障还原模型设置为“完整”
2>
建立一个备份设备jxgl_dev,对应的物理文件名为:
c:
\jxgl_dev.bak;
jxgl_dev'
\jxgl_dev.bak'
;
3>
为jxgl数据库做完全备份至备份设备jxgl_dev;
backupdatabasejxgltojxgl_dev;
4>
向s表中插入一行数据;
insertintosvalues('
98015'
王二'
男'
20,'
IT'
5>
为jxgl数据库做差异备份至备份设备jxgl_dev;
backupdatabasejxgltojxgl_dev
6>
再向s表中插入一行数据;
98016'
张三'
SW'
7>
为jxgl数据库做日志备份至备份设备jxgl_dev;
backuplogjxgltojxgl_dev
8>
删除数据库,并创建新的数据库jxgl,为新数据库jxgl进行完全备份的恢复,查看s表的内容;
dropdatabasejxgl
创建新的jxgl数据库
恢复:
restoredatabasejxglwithrecovery
9>
为jxgl数据库进行差异备份的恢复,查看s表中的内容;
restoredatabasejxglfromjxgl_devwithnorecovery
10>
为jxgl数据库进行事务日志备份的恢复,查看s表的内容;
restorelogjxglfromjxgl_dev
(4)将数据库导出到Access中
创建一个Access数据库jxgl(jxgl.mdb文件),把在SQLSERVER中创建的jxgl数据库导出到Access数据库jxgl中。
四、实验总结
通过本次试验,基本掌握数据库并发控制与恢复备份基础知识;
基本掌握创建、修改、使用、数据库并发控制与恢复的不同方法。