Làm thế nào các bế tắc được phát hiện và báo cáo trong RDBMS?


8

Tôi đã được đưa ra câu hỏi loại bài luận này trong một cuộc phỏng vấn nhưng không nhận được công việc. Câu hỏi đầy đủ như sau:

Làm thế nào các bế tắc được phát hiện và báo cáo trong RDBMS? Chủ giao dịch và nhà phát triển ứng dụng chịu trách nhiệm đảm bảo trong cả hai tình huống phát hiện và phòng ngừa là gì?

Câu trả lời:


13

Trong SQL Server có một luồng riêng định kỳ (mặc định 5 giây, khoảng thời gian thấp hơn nếu phát hiện bế tắc) kiểm tra danh sách chờ cho bất kỳ chu kỳ nào. Tức là nó xác định tài nguyên mà một luồng đang chờ, sau đó nó tìm thấy chủ sở hữu của tài nguyên đó và tìm đệ quy tài nguyên mà chủ đề đó đang chờ đợi, từ đó xác định các luồng đang chờ cho các tài nguyên khác.

Nếu tìm thấy bế tắc thì nạn nhân được chọn sẽ bị giết bằng thuật toán này:

  1. Xác định các chủ đề không phải là không thể thực hiện được (ví dụ như một chủ đề đang quay trở lại một giao dịch là không thể thực hiện được).
  2. Tìm chủ đề với mức ưu tiên bế tắc thấp nhất.
  3. Chọn một cái rẻ nhất để quay trở lại, tức là cái đã làm ít nhất cho đến nay.

Bạn có thể tìm thêm thông tin về phát hiện khóa chết máy chủ SQL tại đây: http://msdn.microsoft.com/en-us/l Library



/ ms178104.aspx Chủ sở hữu giao dịch / nhà phát triển ứng dụng chịu trách nhiệm giảm thiểu rủi ro xảy ra bế tắc và phải làm rằng họ nên:

  1. Hãy chắc chắn để giữ các giao dịch càng ngắn càng tốt. Ví dụ: không hiển thị biểu mẫu đăng nhập sau khi bắt đầu giao dịch và đợi người dùng nhập vào, thay vào đó hãy thu thập tất cả thông tin bạn cần và sau đó chạy giao dịch.
  2. Sử dụng mức cô lập thấp nhất có thể, ví dụ: không đặt tuần tự hóa khi bạn chỉ muốn tạm thời hiển thị một số giá trị cho người dùng. Xin lưu ý rằng việc thiết lập mức cô lập chính xác là một khoa học trong chính nó và nằm ngoài phạm vi trong câu trả lời này.
  3. Nếu bạn là nạn nhân của sự bế tắc, tức là bạn gặp lỗi # 1205, sau đó chạy lại giao dịch của bạn một cách trong suốt cho người dùng của bạn. Vì khác, cạnh tranh, giao dịch giờ đây hy vọng có được các tài nguyên mà nó đang chờ đợi và kết thúc, không giống như bạn sẽ gặp lại bế tắc tương tự.

4. Thu thập tài nguyên và thực hiện cập nhật / xóa / chèn các mẫu theo cùng một thứ tự một cách nhất quán trong toàn bộ ứng dụng.
ErikE

3
@ErikE thường không thể / khả thi để "thực hiện cập nhật / xóa / chèn các mẫu theo cùng một thứ tự nhất quán trong ứng dụng", mặc dù lời khuyên đáng ngờ này rất phổ biến trên Web. Chi tiết tại đây: sqlblog.com/bloss/alexander_kuznetsov/archive/2010/01/15/
AK

1
Điểm tốt. Nhưng tôi vẫn nghĩ rằng nỗ lực này là đáng giá, miễn là người ta không ảo tưởng rằng nó sẽ luôn luôn có thể hoặc luôn luôn khắc phục vấn đề. Điều cha mẹ / con cái rất thú vị, làm thế nào về việc xóa tầng hoặc lấy khóa cập nhật trên các hàng cha mẹ trước? Và nếu bạn hợp nhất mà không có MERGE, tại sao không nhất quán? Tôi xóa-> cập nhật-> chèn cá nhân.
ErikE

1
@AlexKuznetsov: Nó không phải là viên đạn người giải quyết nhưng không nên loại bỏ. Mặc dù vậy, tôi đã giảm (không loại bỏ) các bế tắc theo cách này: thông qua phân tích tĩnh về mã chạy thường xuyên bị bế tắc mỗi ngày hoặc 7. Tôi đề nghị "tối ưu hóa sớm" được áp dụng, v.v.
gbn

Tôi không đồng ý với đề xuất số 3. Khi chúng tôi thử lại sau khi bế tắc, chúng tôi rất có thể sẽ ghi đè lên các thay đổi của các quy trình khác. Chúng ta cần lưu ý rằng rất có thể người khác đã sửa đổi dữ liệu mà chúng ta dự định sửa đổi. Đặc biệt là nếu tất cả các độc giả chạy dưới sự cô lập ảnh chụp nhanh, thì độc giả không thể tham gia vào các bế tắc, điều đó có nghĩa là tất cả các bên liên quan đến bế tắc đều là nhà văn, đã sửa đổi hoặc cố gắng sửa đổi cùng một dữ liệu. Nếu chúng ta chỉ bắt ngoại lệ và tự động thử lại, chúng ta có thể ghi đè lên các thay đổi của người khác. Điều này được gọi là cập nhật bị mất, và điều này thường sai.
AK
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.