Read Committed:SQL 默认级别,读取时设置共享锁,避免其他进程脏读。
实验:初始状态:Ntusername ='1' where rownumber =8
Part I:------------------------------------------------------------------
在默认隔离级别下,执行下面语句(52)进程
begin transaction
update t08102101
set Ntusername ='2'
where rownumber =8
select @@trancount
sp_lock看到的锁信息如下:
52 5 1582628681 1 KEY (08000c080f1b) X GRANT
52 5 1582628681 0 TAB IX GRANT
52 5 1582628681 1 PAG 1:333532 IX GRANT
然后执行下面的语句,(65)进程
set transaction isolation level read committed
select * from t08102101
where rownumber =8
无法完成查询,取不到任何数据,锁信息如下:
52 5 1582628681 1 KEY (08000c080f1b) X GRANT
52 5 1582628681 0 TAB IX GRANT
52 5 1582628681 1 PAG 1:333532 IX GRANT
65 5 1582628681 1 KEY (08000c080f1b) S WAIT
65 5 1582628681 0 TAB IS GRANT
65 5 1582628681 1 PAG 1:333532 IS GRANT
此时执行
select * from t08102101 (nolock)
where rownumber =8
可以得到 Ntusername ='2' where rownumber =8的结果,锁信息没有变化
而在52进程执行
select * from t08102101
where rownumber =8
结果是Ntusername ='2' where rownumber =8
Part II:------------------------------------------------------------------
回滚之前的更新操作,打开read_committed_snapshot开关:
alter database dbcenter
set read_committed_snapshot on
再次执行
begin transaction
update t08102101
set Ntusername ='2'
where rownumber =8
select @@trancount
锁信息如下
52 5 1582628681 1 KEY (08000c080f1b) X GRANT
52 5 1582628681 0 TAB IX GRANT
52 5 1582628681 1 PAG 1:333532 IX GRANT
执行下面的语句,(65)进程
set transaction isolation level read committed
select * from t08102101
where rownumber =8
可以得到Ntusername ='1' where rownumber =8的更新前结果
在另外进程执行(nolock)查询,得到Ntusername ='2' where rownumber =8
此时,sp_lock看到的只有52进程的排他锁信息。
而在52进程中执行
set transaction isolation level read committed
select * from t08102101
where rownumber =8
得到的是Ntusername ='2' where rownumber =8
结论:数据库默认的事务隔离级别是read committed,且该级别不允许读取未提交中的数据
--13:23 2008-12-21