Mic*_*eyn 11 sql-server-2008 sql-server sql-server-2008-r2
我想知道在未提交读隔离级别下脏读“有多脏” 。我知道已更新但尚未提交的行是可见的,但是:
更新:经过一些辩论,最小的共识是,如果列大小大于 8KB,脏读,即使在列本身内,也是可能的。
无论隔离级别如何,两个用户都不能同时更新单个页面,也不能任何用户读取部分更新的页面。试想一下,SQL Server 将如何处理页眉显示 Col3 从第 17 个字节开始的页面。但它实际上从第 25 个字节开始,因为该行的那部分尚未更新。数据库无法处理这种情况。
但是对于大于 8k 的行,将使用多个页面,这使得半更新列成为可能。从 MSDN 链接复制(以防链接断开),在一个窗口中启动此查询:
if object_id('TestTable') is not null
drop table TestTable
create table TestTable (txt nvarchar(max) not null)
go
insert into TestTable select replicate(convert(varchar(max),
char(65+abs(checksum(newid()))%26)),100000)
go 10
update TestTable set txt=replicate(convert(varchar(max),
char(65+abs(checksum(newid()))%26)),100000)
go 100000
Run Code Online (Sandbox Code Playgroud)
这将创建一个表,然后使用 100.000 倍相同字符的字符串对其进行更新。在第一个查询运行时,在另一个窗口中启动此查询:
while 1=1 begin
if exists (select * from TestTable (nolock) where left(Txt,1) <> right(Txt,1))
break
end
Run Code Online (Sandbox Code Playgroud)
第二个查询在读取半更新的列时停止。也就是说,当第一个字符与最后一个字符不同时。它将很快完成,证明可以读取半更新的列。如果删除nolock提示,则第二个查询将永远不会完成。
令人惊讶的结果!半更新的 XML 列可能会破坏(nolock)报告,因为 XML 格式不正确。