Tại sao truy vấn này gây ra bế tắc?


11

Tại sao truy vấn này gây ra bế tắc?

UPDATE TOP(1) system_Queue SET
  [StatusID] = 2,
  @ID = InternalID
WHERE InternalID IN (
    SELECT TOP 1 
      InternalID FROM system_Queue
    WHERE IsOutGoing = @IsOutGoing AND StatusID = 1
ORDER BY MessageID ASC, InternalID ASC)

Biểu đồ bế tắc được thêm vào:

<keylock hobtid="72057594236436480" dbid="9" objectname="Z.dbo.system_Queue" indexname="PK_system_Queue" id="lock5b25cc80" mode="X" associatedObjectId="72057594236436480">
    <owner-list>
     <owner id="processc6fe40" mode="X"/>
    </owner-list>
    <waiter-list>
     <waiter id="processc7b8e8" mode="S" requestType="wait"/>
    </waiter-list>
   </keylock>
   <keylock hobtid="72057594405453824" dbid="9" objectname="Z.dbo.system_Queue" indexname="IX_system_Queue_DirectionByStatus" id="lock48cf3180" mode="S" associatedObjectId="72057594405453824">
    <owner-list>
     <owner id="processc7b8e8" mode="S"/>
    </owner-list>
    <waiter-list>
     <waiter id="processc6fe40" mode="X" requestType="wait"/>
    </waiter-list>
   </keylock>

THÊM:

Cảm ơn Sankar vì bài viết có giải pháp làm thế nào để tránh loại bế tắc này:

  • loại bỏ các cột không cần thiết khỏi trình chiếu của người đọc để anh ta không phải tìm kiếm chỉ mục được nhóm
  • thêm các cột được yêu cầu dưới dạng các cột được chứa vào chỉ mục không được phân cụm để làm cho chỉ mục được bao phủ, một lần nữa để người đọc không tìm kiếm chỉ mục được phân cụm
  • tránh các bản cập nhật phải duy trì chỉ mục không phân cụm

phiên bản nào của nền tảng db mà bạn đang sử dụng? mức cô lập trx (hoặc tương tranh) mặc định là gì? Hiện tại chỉ mục nào tồn tại trên bảng system_Queue?
SQLRockstar

@QueryRockstar một phần của biểu đồ khóa chết được thêm vào, máy chủ sql 2008
garik

@QueryRockstar IX_system_Queue_DirectionByStatus chỉ mục của IsOutGoing và StatusID.
garik

Câu trả lời:


13

Tôi trông như thể bạn đang cố gắng thực hiện CHỌN và CẬP NHẬT trong cùng một tuyên bố và trên cùng một bảng.

CHỌN đang giữ một khóa chia sẻ trên các giá trị bên trong chỉ mục IX_system_Queue_DirectionByStatus và CẬP NHẬT cần cho các khóa đó được phát hành trước khi có thể nhận được khóa độc quyền sẽ cập nhật khóa chính (mà tôi đoán là sẽ được nhóm và cũng là một phần của Giá trị khóa IX_system_Queue_DirectionByStatus).

Dù sao, tôi đoán là truy vấn này sẽ chỉ thành công trong trường hợp hiếm có là các giá trị chỉ mục mà nó đang chọn và cập nhật không xung đột. Có phải nó bế tắc mỗi khi bạn thực thi (tôi cho rằng nó sẽ được).

Đây là một liên kết giải thích các bế tắc chi tiết hơn: http://sqlblog.com/bloss/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx


Chơi lô tô! Cảm ơn bạn. Đó là tình huống thực sự kỳ lạ cho sự bế tắc mà tôi từng thấy. Cảm ơn bạn đã trả lời.
garik

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.