EDITED sau khi đọc liên kết diễn đàn MSDN từ bình luận , rất thú vị.
Bất kể mức độ cô lập, hai người dùng không thể cập nhật đồng thời một trang , và bất kỳ người dùng nào cũng không thể đọc một trang được cập nhật một phần. Chỉ cần tưởng tượng SQL Server sẽ xử lý một trang trong đó tiêu đề cho biết Col3 bắt đầu ở byte 17. Nhưng nó thực sự bắt đầu ở byte 25, bởi vì phần đó của hàng chưa được cập nhật. Không có cách nào một cơ sở dữ liệu có thể xử lý đó.
Nhưng đối với các hàng lớn hơn 8k, nhiều trang được sử dụng và điều đó làm cho một cột được cập nhật một nửa có thể. Sao chép từ liên kết MSDN (trong trường hợp liên kết bị hỏng), hãy bắt đầu truy vấn này trong một cửa sổ:
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
Điều này tạo ra một bảng và sau đó cập nhật nó với một chuỗi 100.000x cùng một ký tự. Trong khi truy vấn đầu tiên đang chạy, hãy bắt đầu truy vấn này trong một cửa sổ khác:
while 1=1 begin
if exists (select * from TestTable (nolock) where left(Txt,1) <> right(Txt,1))
break
end
Truy vấn thứ hai dừng lại khi nó đọc một cột được cập nhật một nửa. Đó là, khi nhân vật đầu tiên khác với nhân vật cuối cùng. Nó sẽ kết thúc nhanh chóng, chứng minh rằng có thể đọc các cột được cập nhật một nửa. Nếu bạn xóa nolock
gợi ý, truy vấn thứ hai sẽ không bao giờ kết thúc.
Kết quả đáng ngạc nhiên! Một cột XML được cập nhật một nửa có thể phá vỡ một (nolock)
báo cáo, vì XML sẽ không đúng định dạng.