Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Tại sao truy vấn SQL Server này bị khóa?

  • process 9196a8 có trang 151867 slot 174 ở chế độ X và muốn trang 140302 slot 31 ở chế độ S
  • process 88b5b8 có trang 140302 khe 31 ở chế độ X và muốn trang 151867 khe 174 ở chế độ S
  • hai lần xóa chạy trong isolationlevel="repeatable read (3)"

Vì vậy, deadlock xảy ra trên heap cơ sở của bảng (RID khóa thay vì khóa key ngụ ý một heap không phải là Btree). Mức độ cô lập cao (có thể do DTC gây ra, xét từ tên xact) làm cho cài đặt RCSI không liên quan.

Loại cột PARTYEXTERNALREF và PARTYTYPE là gì? Các tham số được truyền vào là NVARCHAR (tức là. Unicode) và nếu các cột là VARCHAR (tức là. Ascii) thì do các quy tắc của ưu tiên kiểu dữ liệu chỉ số NC sẽ không được sử dụng. Do có liên quan đến quá trình quét bảng, cùng với mức độ cách ly cao đang được sử dụng, nên sự cố gần như không thể tránh khỏi.

Giải pháp là sử dụng các tham số kiểu VARCHAR cho @ P0 và @ P1 để chỉ mục NC sẽ được tận dụng để tránh việc quét bảng.

Nếu các tham số đã thuộc loại VARCHAR và bạn có thể xác nhận từ kế hoạch thực thi rằng một tìm kiếm trên NC được sử dụng, câu hỏi đầu tiên của tôi sẽ là khác giao dịch đang thực hiện, ngoài các câu lệnh xóa?

BTW, bạn chỉ cung cấp tên của chỉ số NC nhưng tôi giả sử là trên (PARTYEXTERNALREF, ISCOUNTERPARTY, PARTYID) .

Cập nhật

Vì nhận xét của bạn nói rằng các cột NVARCHAR thì giả thuyết quét bảng có lẽ là sai. Có ba khả năng nữa gây ra bế tắc cần được điều tra:

  • bất kỳ câu lệnh nào khác được thực hiện bởi giao dịch trước khi DELETE (điều này có thể xảy ra nhất)
  • bất kỳ sự chồng chéo nào trong các hàng được chọn bởi hai câu lệnh DELETE có liên quan đến bế tắc
  • xung đột băm

Đối với hai giả thuyết đầu tiên, chỉ bạn có thể làm bất cứ điều gì ngay bây giờ (điều tra xem chúng có đúng không). Đối với điều cuối cùng, tôi có thể cho bạn biết làm thế nào để xác minh nó, nhưng không phải là tầm thường. Nó khó có thể xảy ra và một chút khó khăn để chứng minh, nhưng nó là có thể. Vì bạn biết đó là trường hợp bế tắc (XML đính kèm), hãy sử dụng nó làm cơ sở điều tra:

  • khôi phục bản sao tại thời điểm của cơ sở dữ liệu dừng lại ở 2011-09-02T19:00:29.690
  • chạy DBCC TRACEON(3604,-1)
  • sử dụng DBCC PAGE (<restored db id>, 1, 151867, 3) kiểm tra các giá trị trong vị trí 174
  • sử dụng DBCC PAGE (, 1, 140302, 3) `kiểm tra các giá trị tại vị trí 31
  • chạy SELECT %%lockres%% FROM PARTIES WHERE PARTYEXTERNALREF = ... AND ISCOUNTERPARTY='N' and PARTYID=... và chuyển các giá trị đã đọc ở trên
  • so sánh các giá trị băm khóa kết quả, nếu chúng khớp nhau thì bạn có xung đột băm và điều này gây ra bế tắc.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Điểm danh VÀO VÀ NGOÀI

  2. Làm cách nào để xem các kết nối SQL Server đang hoạt động?

  3. Các giới hạn NVARCHAR và VARCHAR trong SQL

  4. SQL Server 2008- Nhận các ràng buộc bảng

  5. Nhận N hàng cuối cùng từ bảng với một thủ tục được lưu trữ