コメントからMSDNフォーラムのリンクを読んだ後、編集されました。非常に興味深いです。
分離レベルに関係なく、2人のユーザーが1つのページを同時に更新したり、部分的に更新されたページを読み取ることはできません。ヘッダーにCol3がバイト17から始まると書かれたページをSQL Serverがどのように処理するかを想像してみてください。しかし、行のその部分はまだ更新されていないため、実際にはバイト25から始まります。データベースがそれを処理できる方法はありません。
ただし、8kより大きい行の場合、複数のページが使用されるため、半分更新された列が可能になります。MSDNリンクからコピーした場合(リンクが壊れた場合)、このクエリを1つのウィンドウで開始します。
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
これによりテーブルが作成され、同じ文字の100.000xの文字列で更新されます。最初のクエリの実行中に、このクエリを別のウィンドウで開始します。
while 1=1 begin
if exists (select * from TestTable (nolock) where left(Txt,1) <> right(Txt,1))
break
end
2番目のクエリは、半分更新された列を読み取ると停止します。つまり、最初の文字が最後の文字と異なる場合です。それはすぐに終了し、半分更新された列を読み取ることができることを証明します。nolock
ヒントを削除すると、2番目のクエリは終了しません。
意外な結果!(nolock)
XMLの形式が正しくないため、半分更新されたXML列はレポートを壊す可能性があります。