Bạn nhầm lẫn về UPDLOCK, HOLDLOCK


89

Trong khi nghiên cứu việc sử dụng Bảng Gợi ý , tôi gặp hai câu hỏi sau:

Câu trả lời cho cả hai câu hỏi nói rằng khi sử dụng (UPDLOCK, HOLDLOCK), các quy trình khác sẽ không thể đọc dữ liệu trên bảng đó, nhưng tôi không thấy điều này. Để kiểm tra, tôi đã tạo một bảng và khởi động hai cửa sổ SSMS. Từ cửa sổ đầu tiên, tôi đã chạy một giao dịch được chọn từ bảng bằng cách sử dụng các gợi ý bảng khác nhau. Trong khi giao dịch đang chạy, từ cửa sổ thứ hai, tôi chạy các câu lệnh khác nhau để xem cái nào sẽ bị chặn.

Bảng kiểm tra:

CREATE TABLE [dbo].[Test](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Value] [nvarchar](50) NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Từ SSMS Window 1:

BEGIN TRANSACTION

SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'

COMMIT TRANSACTION

Từ SSMS Window 2 (chạy một trong những thao tác sau):

SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'

Ảnh hưởng của các gợi ý bảng khác nhau đối với các câu lệnh chạy trong Window 2:

           (UPDLOCK)       (HOLDLOCK)    (UPDLOCK, HOLDLOCK)    (TABLOCKX)
---------------------------------------------------------------------------
SELECT    not blocked      not blocked       not blocked         blocked
INSERT    not blocked        blocked           blocked           blocked
UPDATE      blocked          blocked           blocked           blocked
DELETE      blocked          blocked           blocked           blocked

Tôi đã hiểu sai câu trả lời được đưa ra trong những câu hỏi đó hoặc mắc lỗi trong bài kiểm tra của mình? Nếu không, tại sao bạn sẽ sử dụng (UPDLOCK, HOLDLOCK)so với (HOLDLOCK)một mình?


Giải thích thêm về những gì tôi đang cố gắng hoàn thành:

Tôi muốn chọn các hàng từ một bảng và ngăn không cho dữ liệu trong bảng đó bị sửa đổi khi đang xử lý. Tôi không sửa đổi dữ liệu đó và muốn cho phép đọc xảy ra.

Câu trả lời này nói rõ rằng điều đó (UPDLOCK, HOLDLOCK)sẽ chặn lượt đọc (không phải những gì tôi muốn). Các nhận xét về câu trả lời này ngụ ý rằng nó HOLDLOCKngăn cản việc đọc. Để thử và hiểu rõ hơn về tác dụng của các gợi ý trong bảng và xem liệu UPDLOCKmột mình có làm được những gì tôi muốn hay không, tôi đã thực hiện thí nghiệm trên và nhận được kết quả trái ngược với những câu trả lời đó.

Hiện tại, tôi tin rằng đó (HOLDLOCK)là những gì tôi nên sử dụng, nhưng tôi lo ngại rằng tôi có thể đã mắc sai lầm hoặc bỏ qua thứ gì đó sẽ quay lại cắn tôi trong tương lai, do đó, câu hỏi này.

Câu trả lời:


102

Tại sao khối UPDLOCK lại chọn? Các Khóa Compatibility Matrix rõ chương trình Ncho S / U và U / S tranh, như trong Không xung đột .

Đối với HOLDLOCK gợi ý tài liệu cho biết:

HOLDLOCK: Tương đương với SERIALIZABLE. Để biết thêm thông tin, hãy xem SERIALIZABLE sau trong chủ đề này.

...

SERIALIZABLE: ... Quá trình quét được thực hiện với ngữ nghĩa giống như một giao dịch đang chạy ở mức cô lập SERIALIZABLE ...

và chủ đề Mức cô lập giao dịch giải thích ý nghĩa của SERIALIZABLE:

Không có giao dịch nào khác có thể sửa đổi dữ liệu đã được giao dịch hiện tại đọc cho đến khi giao dịch hiện tại hoàn tất.

Các giao dịch khác không thể chèn các hàng mới với các giá trị khóa nằm trong phạm vi khóa được đọc bởi bất kỳ câu lệnh nào trong giao dịch hiện tại cho đến khi giao dịch hiện tại hoàn tất.

Do đó, hành vi bạn thấy được giải thích hoàn hảo bởi tài liệu sản phẩm:

  • UPDLOCK không chặn đồng thời CHỌN và CHÈN, nhưng chặn bất kỳ CẬP NHẬT hoặc XÓA các hàng được chọn bởi T1
  • HOLDLOCK có nghĩa là KHOÁNG LÃNH và do đó cho phép CHỌN, nhưng chặn CẬP NHẬT và XÓA các hàng được chọn bởi T1, cũng như bất kỳ CHÈN nào trong phạm vi được chọn bởi T1 (là toàn bộ bảng, do đó bất kỳ chèn nào ).
  • (UPDLOCK, HOLDLOCK): thử nghiệm của bạn không hiển thị những gì sẽ chặn ngoài trường hợp trên, cụ thể là một giao dịch khác với UPDLOCK trong T2 :
    SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
  • TABLOCKX không cần giải thích

Câu hỏi thực sự là bạn đang cố gắng đạt được điều gì? Chơi với các gợi ý về khóa với sự hiểu biết hoàn toàn tuyệt đối 110% về ngữ nghĩa khóa đang cầu xin sự rắc rối ...

Sau khi OP chỉnh sửa:

Tôi muốn chọn các hàng từ một bảng và ngăn không cho dữ liệu trong bảng đó bị sửa đổi khi đang xử lý.

Bạn nên sử dụng một trong các mức cách ly giao dịch cao hơn. REPEATABLE READ sẽ ngăn không cho dữ liệu bạn đọc bị sửa đổi. SERIALIZABLE sẽ ngăn không cho dữ liệu bạn đọc bị sửa đổi dữ liệu mới được chèn vào. Sử dụng các mức cách ly giao dịch là cách tiếp cận phù hợp, trái ngược với việc sử dụng gợi ý truy vấn. Kendra Little có một áp phích đẹp thể hiện các cấp độ cô lập .


+1 và cảm ơn bạn đã trả lời chi tiết. Tôi sẽ cập nhật câu hỏi của mình để thêm chi tiết mục tiêu của tôi là gì.
Jeff Ogata

1
@Remus Rusanu, bạn có thể vui lòng giải thích lý do tại sao cách tiếp cận đúng là sử dụng các mức cô lập thay vì sử dụng gợi ý truy vấn không? Tôi có một thủ tục mà tôi chỉ cần khóa hai bảng để không bị sửa đổi và tôi đang sử dụng TABLOCK, HOLDLOCK, liệu tôi có thực sự nên thay đổi sang mức cô lập và khóa tất cả các bảng trong giao dịch của mình không?
Steve

Tôi có thể muốn giải thích cho TABLOCKX :)
niico

Lưu ý: Liên kết cho mục nhập blog cho Kendra Little trả về 404. Tôi không thể tìm thấy mục nào ghi ngày 2 tháng 2 năm 2011, như liên kết gợi ý.
Bacon Bits

22

UPDLOCK được sử dụng khi bạn muốn khóa một hàng hoặc các hàng trong một câu lệnh chọn cho một câu lệnh cập nhật trong tương lai. Bản cập nhật trong tương lai có thể là tuyên bố tiếp theo trong giao dịch.

Các phiên khác vẫn có thể xem dữ liệu. Họ chỉ không thể lấy được các khóa không tương thích với UPDLOCK và / hoặc HOLDLOCK.

Bạn sử dụng UPDLOCK khi muốn để các phiên khác không thay đổi các hàng bạn đã khóa. Nó hạn chế khả năng cập nhật hoặc xóa các hàng bị khóa của họ.

Bạn sử dụng HOLDLOCK khi muốn giữ cho các phiên khác không thay đổi bất kỳ dữ liệu nào bạn đang xem. Nó hạn chế khả năng chèn, cập nhật hoặc xóa các hàng bạn đã khóa. Điều này cho phép bạn chạy lại truy vấn và xem kết quả tương tự.


1
Cảm ơn bạn, nhưng tôi không nghĩ rằng bạn đã thực sự trả lời câu hỏi của tôi: câu trả lời cho những câu hỏi đó có sai trong việc nêu rõ số lần (UPDLOCK,HOLDLOCK)đọc khối đó không và có lý do gì để sử dụng (UPDLOCK,HOLDLOCK)thay vì chỉ (HOLDLOCK)?
Jeff Ogata,

Câu thứ hai của tôi trả lời câu hỏi của bạn, họ sai. Các phiên khác vẫn có thể đọc dữ liệu.
Scott Bruns

Updlock, Holdlock không giống như holdlock. Updlock, holdlock khóa các hàng để cập nhật và tuần tự hóa giao dịch của bạn. Holdlock tự nó chỉ tuần tự hóa giao dịch của bạn. Nó không khóa các hàng đã chọn để truy cập thêm.
Scott Bruns

"UPDLOCK được sử dụng khi bạn muốn khóa một hàng hoặc các hàng trong một câu lệnh chọn cho một câu lệnh cập nhật trong tương lai." Tôi thích điều này, vì XLOCK đôi khi có thể không hoạt động
Yiping
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.