日期:2014-05-18 浏览次数:20732 次
-- 建测试表ap,yx字段没索引. create table ap ( Id int not null, yx char(8000) not null constraint pk_ap primary key clustered (Id) ) -- 插入5笔记录: 40,41,42,43,44. insert into ap select 40,'ap0405140_0' insert into ap select 41,'ap0405140_1' insert into ap select 42,'ap0405140_2' insert into ap select 43,'ap0405140_3' insert into ap select 44,'ap0405140_4' select * from ap Id yx ----------- --------------- 40 ap0405140_0 41 ap0405140_1 42 ap0405140_2 43 ap0405140_3 44 ap0405140_4 -- 用dbcc ind()及dbcc page()获取记录与页的对应关系. /* [Id] PagePID ------------------------ 40 148 41 174 42 175 43 192 44 193 */ -- 1.测试read uncommitted时的锁 set transaction isolation level read uncommitted begin tran update ap set yx='ap0405140_16' where yx like '%3' --> 执行计划: Clustered Index Scan, 锁范围: PagePID 192 IX锁 rollback tran -- 2.测试read committed时的锁 set transaction isolation level read committed begin tran update ap set yx='ap0405140_16' where yx like '%3' --> 执行计划: Clustered Index Scan, 锁范围: PagePID 192 IX锁 rollback tran -- 3.测试repeatable read时的锁 set transaction isolation level repeatable read begin tran update ap set yx='ap0405140_16' where yx like '%3' --> 执行计划: Clustered Index Scan, 锁范围: PagePID 148 IU锁,175 IU锁,174 IU锁,193 IU锁,192 IX锁. rollback tran -- 4.测试serializable时的锁 set transaction isolation level serializable begin tran update ap set yx='ap0405140_16' where yx like '%3' --> 执行计划: Clustered Index Scan, 锁范围: PagePID 148 IU锁,175 IU锁,174 IU锁,193 IU锁,192 IX锁. rollback tran
--可重复读 begin tran select * from student where sno=2006001 --读完了这一条共享锁不释放掉..我不释放掉共享..你两一个事务的排他就不能修改..排他共享不能共存 --他只有等到 这个事务commit掉后才会释放掉共享锁...所以事务2 进行修改就必须等待.. select * from student where sno=2006001 --这里和上一条的结果是完全一样的..因为上一条为该行上了共享不释放,其他修改不了. commit tran --这个时候才释放掉了行的共享锁.. begin tran2 update student set sname='大力水手' --修改不掉..必须等待 上一个事务释放掉共享锁才能修改. end tran2 但是,这个可重复读得事务隔离级别是保证了..读锁一只保持..重复读可以了..解决不了幻读 --可串行 没有锁现象. 在数据集上防止一个范围锁, 以防止其他用户在事务完成之前更新数据集或插入数据集内.这个级别限制最大.该级别作用与在事务内所有select 语句中所有表上设置holdlock相同. 也就是上了一个范围锁.最高级别,并发最低.如果你查询的数据量比较大..跟表锁没有什么区别了! 其工作原理: 事务中的锁被报纸在一个更高的级别上,利用索引产生 key range 锁,从而阻止对数据集插入. 为了防止向数据集插入行,数据集需要锁定,如果没有合适的索引,那么便又可能产生更高级别的锁,如 表锁,而非范围锁. --避免幻读,隔离级别可串行化..上范围锁 begin tran select a from t where country='ch' --读出a=5 select a from t where country='ch' --读出a=5 commit tran 事务2 insert into t values(6,'ch') --由于支队'ch'加了范围锁..所以insert语句将等到事务1 提交后才执行 --如果事务1 查询的数据量比较大..就相当于..锁了整个表
------解决方案--------------------
有时候,系统会隐式地加一些锁,我们也可以利用一下的。
------解决方案--------------------