Khi bạn chạy hai câu lệnh đồng thời (một SELECT và UPDATE), hành vi thực tế sẽ cơ bản là ngẫu nhiên. Điều này là do không phải thao tác nào là tức thời. Để đơn giản hóa, hãy xem xét bảng của bạn một danh sách và SELECT đang duyệt qua danh sách này, nhìn vào một hàng tại một thời điểm. CẬP NHẬT cũng đang cố cập nhật một hoặc nhiều hàng. Khi UPDATE đang cố gắng cập nhật một hàng đằng sau lệnh SELECT thì không có gì xảy ra (không chặn) vì SELECT đã tiến triển qua điểm UPDATE. Nếu CẬP NHẬT đang cố gắng cập nhật hàng mà tại đó SELECT đang tìm kiếm ngay bây giờ thì UPDATE sẽ phải chờ SELECT để tiếp tục, điều này sẽ diễn ra rất rất nhanh và UPDATE sẽ bỏ chặn và thành công, trong khi SELECT đang tiến lên phía trước. Nhưng nếu UPDATE đang cập nhật một hàng trước của CHỌN thì bản cập nhật sẽ thành công và, sau, SELECT cuối cùng sẽ đạt được chính xác hàng này và sẽ dừng lại, bị chặn.Bây giờ, SELECT phải đợi cho đến khi giao dịch đã thực hiện UPDATE cam kết.
Đây là câu chuyện được đơn giản hóa. Cuộc sống thực tế phức tạp hơn nhiều. SELECT có thể có nhiều điểm đọc (kế hoạch song song). Cả SELECT và UPDATE đều có thể chọn một đường dẫn truy cập, có nghĩa là sử dụng một hoặc nhiều chỉ mục phụ để định vị các hàng. Truy vấn phức tạp có thể chứa các toán tử gây ra nhiều lần tra cứu vào một bảng (ví dụ: các phép nối). Cả SELECT và UPDATE đều có thể thực hiện tra cứu bookmark để tìm nạp dữ liệu BLOB, thay đổi đáng kể hành vi khóa. Ước tính Cardinality có thể khiến cho SELECT chạy ở chế độ khóa chi tiết cao (ví dụ: khóa chia sẻ mức bảng). CẬP NHẬT có thể kích hoạt khóa leo thang và sự leo thang có thể thất bại hoặc thành công. Choosing different access paths can lead to deadlock. False lock contention can occur due to hash collisions. Chỉ có khoảng một vô số các biến có tiếng nói trong này. Và tôi thậm chí không đề cập đến mức cô lập cao hơn (đọc lặp lại, có thể tuần tự hóa).
Có lẽ bạn nên sử dụng cách ly SNAPSHOT và ngừng lo lắng về vấn đề này?
Nguồn
2012-08-06 14:03:57
Bạn đang nói về mức cô lập giao dịch nào? – Oded
@Oded Mặc định - Tôi tin rằng nó đã được đọc. –
* "hiện tại tôi không quan tâm đến dữ liệu bẩn" *: hãy cẩn thận [những gì bạn mong muốn] (http://blogs.msdn.com/b/sqlcat/archive/2007/02/01/previously-committed- rows-might-be-miss-if-nolock-hint-is-used.aspx). –