Tôi đang thiết lập một trường hợp thử nghiệm để chứng minh một kịch bản bế tắc nhất định và yêu cầu một số hiểu biết sâu sắc về những gì đang xảy ra. Tôi có một bảng heap, được gọi là HeapTable. Bảng này được cập nhật bởi 2 giao dịch mô phỏng.
Giao dịch 1:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Dylan'
WHERE FirstName = 'Ovidiu';
WAITFOR DELAY '00:00:15';
UPDATE HeapTable
SET FirstName = 'Bob'
WHERE FirstName = 'Thierry';
ROLLBACK TRANSACTION
Giao dịch 2:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';
ROLLBACK TRAN
Tôi loại bỏ giao dịch 1 trước, theo sát là giao dịch 2. Vì giao dịch dự kiến 1 sẽ yêu cầu một số khóa độc quyền, cùng với một số mục đích độc quyền. Giao dịch 2 sẽ đến và yêu cầu khóa Cập nhật trên cùng RID:
spid dbid ObjId IndId Type Resource Mode Status
55 5 711673583 0 RID 1:24336:10 X GRANT
57 5 711673583 0 RID 1:24336:10 U WAIT
Tôi đã rất ngạc nhiên khi thấy giao dịch thứ hai yêu cầu khóa Cập nhật trên cùng một RID, vì tôi nghĩ rằng điều này chỉ vào một bản ghi duy nhất và cả hai câu lệnh cập nhật xử lý các dữ liệu khác nhau. Thay vào đó, tôi đã mong đợi một cuộc xung đột ở cấp độ trang.
Khi bản cập nhật thứ hai của giao dịch 1 khởi động trong giao dịch 2 sẽ được coi là nạn nhân bế tắc dẫn đến sự quay trở lại của giao dịch 2 và hoàn thành giao dịch 1.
Ai đó có thể giải thích cho tôi tại sao giao dịch thứ hai sẽ yêu cầu khóa cập nhật trên cùng một RID mặc dù cập nhật một bản ghi khác không?
Tôi biết cách khắc phục điều này (ví dụ với một chỉ mục). Tôi không tìm cách khắc phục, tôi thực sự đang tìm lời giải thích tại sao 2 Cập nhật xử lý các bản ghi khác nhau trong một đống sẽ muốn khóa cùng một RID. Tôi đang sử dụng đọc cách ly cam kết. Không có chỉ mục không bao gồm trên bảng.