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

Câu hỏi về SQL Deadlock

SELECT không thể khóa với SELECT khác, bởi vì chúng chỉ có được các khóa được chia sẻ. Bạn nói rằng chúng tôi nên xem xét rằng các CHỌN này hiện 'yêu cầu các khóa đọc độc quyền', nhưng chúng tôi không thể xem xét điều này vì 1) không có cái gọi là exlusive read lock và 2) các lần đọc không nhận được các khóa độc quyền.

Nhưng bạn đặt ra một câu hỏi tổng quát hơn, liệu những câu lệnh đơn giản có thể gây bế tắc hay không. Câu trả lời là chắc chắn, vang dội . Các khóa được thu thập khi thực thi, không được phân tích trước và được sắp xếp sau đó được mua lại theo một số thứ tự. Công cụ sẽ không thể biết trước các khóa cần thiết vì chúng phụ thuộc vào dữ liệu thực tế trên đĩa và để đọc dữ liệu, công cụ cần phải ... khóa dữ liệu.

Những bế tắc giữa các câu lệnh đơn giản (SELECt so với UPDATE hoặc SELECT so với DELETE) do thứ tự truy cập chỉ mục khác nhau là khá phổ biến và rất dễ điều tra, chẩn đoán và sửa chữa. Nhưng lưu ý rằng có luôn luôn một thao tác ghi liên quan, vì các lần đọc không thể chặn lẫn nhau. Đối với cuộc thảo luận này, việc thêm gợi ý UPDLOCK hoặc XLOCK vào SELECT nên được coi là một bài viết. Bạn thậm chí không cần JOIN, một chỉ mục phụ cũng có thể gây ra vấn đề thứ tự truy cập dẫn đến bế tắc, hãy xem Read / Write Deadlock .

Và cuối cùng, viết SELECT FROM A JOIN B hoặc viết SELECT FROM B JOIN A là hoàn toàn không liên quan. Trình tối ưu hóa truy vấn có thể tự do sắp xếp lại thứ tự truy cập khi nó thấy phù hợp, văn bản thực tế của truy vấn không áp đặt thứ tự thực hiện theo bất kỳ cách nào.

Đã cập nhật

Tôi e rằng không có công thức cắt bánh quy. Giải pháp sẽ tùy thuộc vào từng trường hợp. Cuối cùng, trong các ứng dụng cơ sở dữ liệu, bế tắc là một thực tế của cuộc sống. Tôi hiểu điều này nghe có vẻ vô lý, như trong 'chúng tôi đã hạ cánh trên Mặt trăng nhưng chúng tôi không thể viết một ứng dụng cơ sở dữ liệu chính xác', nhưng có những yếu tố mạnh mẽ đảm bảo rằng các ứng dụng cuối cùng sẽ gặp phải bế tắc. Bế tắc may mắn là the dễ nhất để đối phó với lỗi, đơn giản đọc lại trạng thái, áp dụng logic, viết lại trạng thái mới. Bây giờ đang được nói, có một số thực hành tốt có thể giảm đáng kể tần suất bế tắc, đến mức chúng hoàn toàn biến mất:

  • Cố gắng có một mẫu truy cập nhất quán cho Viết . Có các quy tắc được xác định rõ ràng nêu rõ những điều chẳng hạn như 'một giao dịch sẽ luôn được sắp xếp theo thứ tự sau:Customers -> OrderHeaders -> OrderLines . ' Lưu ý rằng lệnh phải được tuân theo bên trong một giao dịch . Về cơ bản, xếp hạng tất cả bảng trong lược đồ của bạn và chỉ định rằng tất cả các cập nhật phải xảy ra theo thứ tự xếp hạng. Điều này cuối cùng rút ra được kỷ luật về mã của cá nhân người đóng góp viết mã, vì nó phải đảm bảo rằng nó viết và cập nhật đúng thứ tự bên trong một giao dịch.
  • Giảm thời lượng trong số các lần viết. Sự khôn ngoan thông thường diễn ra như sau:khi bắt đầu giao dịch thực hiện tất cả các lần đọc (đọc trạng thái hiện có), sau đó xử lý logic và tính toán các giá trị mới, sau đó viết tất cả các cập nhật khi kết thúc giao dịch. Tránh mô hình như 'read-> write-> logic-> read-> write', thay vào đó hãy làm 'read-> read-> logic-> write-> write'. Tất nhiên, sự khéo léo thực sự bao gồm cách giải quyết các trường hợp thực tế, thực tế, cá nhân khi rõ ràng là một phải phải làm ghi giữa giao dịch. Một lưu ý đặc biệt ở đây phải được nói đến về một loại giao dịch cụ thể:những giao dịch được điều khiển bởi một hàng đợi, theo định nghĩa thì bắt đầu hoạt động của chúng bằng cách dequeueing (=một ghi) từ hàng đợi. Những ứng dụng này luôn nổi tiếng là khó viết và dễ bị lỗi (đặc biệt là deadlock), may mắn là vẫn có cách để làm điều đó, hãy xem Sử dụng bảng làm Hàng đợi .
  • Giảm số lượng đọc. Quét bảng là the nguyên nhân phổ biến nhất của bế tắc. Việc lập chỉ mục phù hợp không chỉ giúp loại bỏ những bế tắc mà còn có thể thúc đẩy hiệu suất trong quá trình này.
  • Cách ly ảnh chụp nhanh . Đây là điều gần nhất bạn sẽ nhận được bữa trưa miễn phí liên quan đến việc tránh bế tắc. Tôi cố ý đặt nó cuối cùng, vì nó có thể mặt nạ các vấn đề khác (như lập chỉ mục không đúng) thay vì sửa chữa chúng.

Đang cố gắng giải quyết vấn đề này bằng LockCustomerByXXX Tôi e rằng cách tiếp cận không hiệu quả. Khóa bi quan không mở rộng. Đồng thời lạc quan cập nhật là the cách tiếp tục nếu bạn muốn có bất kỳ loại hiệu suất tốt nào.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kiểm tra sao lưu máy chủ SQL

  2. Khái niệm cơ bản về Nhật ký giao dịch SQL Server

  3. Có bất kỳ vấn đề về Hiệu suất nào khi sử dụng ISNULL () trong SQL Server không?

  4. CONCAT_WS () dành cho SQL Server

  5. SQL Server sp_ExecuteSQL và các kế hoạch thực thi