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

Cơ bản và cách sử dụng gợi ý NOLOCK trong SQL Server

Ý tưởng chính của cơ chế khóa SQL Server là nó kiểm soát tính nhất quán của các giao dịch. Theo nguyên tắc này, nếu một tiến trình muốn thực hiện các thao tác chèn, xóa hoặc cập nhật, SQL Server engine sẽ khóa hàng hoặc các hàng và không cho phép một tiến trình khác cho đến khi giao dịch được hoàn thành. Trong một số trường hợp, cơ chế khóa này có thể dẫn đến các vấn đề về hiệu suất như áp suất quy trình đồng thời cao. Vì vậy, bạn có thể gặp phải vấn đề bế tắc (Bế tắc là một vấn đề đồng thời trong đó hai giao dịch muốn truy cập cùng một dữ liệu đồng thời) các vấn đề trong cơ sở dữ liệu của bạn. Trong bài viết này, chúng tôi sẽ tập trung vào cách tránh các vấn đề về khóa với sự trợ giúp của gợi ý NOLOCK. Trước tiên, chúng ta hãy tìm hiểu những điều cơ bản và chi tiết chính của phương pháp đọc bẩn vì gợi ý NOLOCK có thể khiến đọc bẩn.

Đọc bẩn: Trong phương pháp đọc này, quá trình đọc đọc dữ liệu không được cam kết và quá trình đọc không quan tâm đến các giao dịch đang mở, do đó các khóa không dẫn đến bất kỳ vấn đề nào trong quá trình đọc. Kết quả là, kiểu đọc này làm giảm các vấn đề về khóa. Tuy nhiên, phương pháp đọc bẩn có ưu và nhược điểm vì đọc bẩn có thể gây ra các vấn đề không nhất quán trong tập kết quả của câu lệnh SELECT. Như đã lưu ý, bộ kết quả này có thể bao gồm dữ liệu giao dịch chưa được cam kết, đó là lý do tại sao chúng tôi phải xem xét việc đọc sai khi quyết định thực hiện loại đọc này. Chúng tôi không thể chắc chắn về độ chính xác của các hàng mà chúng tôi thực hiện trong quá trình đọc bẩn vì những hàng này có thể bị cuộn lại. Mặt khác, kiểu đọc này cho phép chúng tôi tránh các vấn đề về khóa và tăng hiệu suất của SQL Server.

KHÔNG CHỮA: Mức cô lập mặc định của SQL Server là Đọc cam kết và ở mức cô lập này, SQL Server không cho phép đọc các đối tượng bị khóa bị khóa bởi các giao dịch không cam kết. Ngoài ra, các đối tượng bị khóa này có thể được thay đổi theo mức độ khóa.

Lưu ý:Trong bài viết Khái niệm chính về khóa SQL Server này, bạn có thể tìm thấy thông tin chi tiết về khóa và báo cáo khóa.

Hãy tưởng tượng rằng bạn có hai người dùng cơ sở dữ liệu và những người dùng này muốn thực hiện thao tác cập nhật và chọn đối với cơ sở dữ liệu. Người dùng đầu tiên bắt đầu cập nhật một hàng cụ thể trong bảng và sau đó người dùng khác muốn đọc cùng một hàng. Hai người dùng này thực hiện các câu lệnh cập nhật và chọn sau, được minh họa trong hình ảnh bên dưới.

Trong trường hợp này, user2 đợi ít nhất 10 giây và sau đó giao dịch sẽ được user1 quay lại và sau đó user2 có thể đọc hàng màu xanh lá cây vì hàng bị khóa sẽ được giải phóng bởi user1. Đây là hành vi mặc định của mức cách ly SQL Server Read được cam kết.

Bây giờ, chúng tôi sẽ chứng minh trường hợp này trong SQL Server. Trước hết, chúng ta sẽ tạo bảng FruitSales và các hàng của nó.

 TẠO BẢNG FruitSales (Id INT IDENTITY (1,1) PRIMARY KEY, [Name] Varchar (20), SalesTotal Float) GOINSERT INTO FruitSales VALUES ('Apple', 10), ('Orange', 8), ( 'Chuối', 2) 

Trong bước này, chúng tôi sẽ mở hai cửa sổ truy vấn SQL Server Management Studio và thực thi truy vấn user1, sau đó thực thi truy vấn user2.

 --- USER1 ---- BẮT ĐẦU CẬP NHẬT FruitSales SET SalesTotal =20 WHERE Id =2 WAITFOR DELAY '00:00:10 'GIAO DỊCH QUAY LẠI --- USER2 ---- ĐẶT THỐNG KÊ THỜI GIAN BẬT * TỪ FruitSales Ở ĐÂU Id =2 

Như bạn có thể thấy trong hình trên, truy vấn thứ hai đợi cho đến khi khôi phục giao dịch user1.

Bây giờ, chúng ta sẽ thảo luận về gợi ý NOLOCK và chi tiết sử dụng. Gợi ý NOLOCK là gợi ý bảng phổ biến nhất được các nhà phát triển cơ sở dữ liệu và quản trị viên sử dụng để loại bỏ các vấn đề về khóa trong cơ sở dữ liệu SQL Server. Với sự trợ giúp của gợi ý bảng NOLOCK, chúng ta có thể đọc các đối tượng bị khóa (hàng, trang hoặc bảng) bị khóa bởi các giao dịch đang mở. Gợi ý NOLOCK ghi đè hành vi mặc định của trình tối ưu hóa truy vấn SQL Server để câu lệnh select có thể đọc các đối tượng bị khóa.

Bây giờ, chúng tôi sẽ thêm gợi ý NOLOCK vào câu lệnh user2 select, sau đó bắt đầu cập nhật user1 và sau đó thực thi câu lệnh user2 select.

 --- USER1 ---- BẮT ĐẦU CẬP NHẬT FruitSales SET SalesTotal =20 WHERE Id =2 WAITFOR DELAY '00:00:10 'GIAO DỊCH GHI LẠI --- USER2 ---- ĐẶT THỐNG KÊ THỜI GIAN BẬT * TỪ FruitSales VỚI (KHÔNG CHỮA) WHERE Id =2 

Trong bước này, chúng tôi sẽ giải thích cách tác động đến gợi ý NOLOCK trên câu lệnh user2 select. Người dùng1 thực hiện câu lệnh đã cập nhật trong một giao dịch rõ ràng và sau đó người dùng2 thực hiện câu lệnh select và tập kết quả trả về không chậm trễ khi hoàn thành giao dịch. Đây là ý tưởng chính của NOLOCK, nó đọc các đối tượng bị khóa.

Bây giờ, chúng ta sẽ tập trung vào tập kết quả của câu lệnh select. Câu lệnh user2 select đã truy xuất giá trị SalesTotal 20 nhưng giá trị thực tế của SalesTotal vẫn là 8. Hãy nhớ rằng nếu bạn đang sử dụng gợi ý bảng NOLOCK trong câu lệnh select của mình, bạn có thể phải đối mặt với loại kết quả dữ liệu không chính xác này.

Mẹo: Từ khóa “WITH” là một tính năng không được dùng nữa, vì vậy Microsoft khuyên bạn không nên sử dụng nó trong quá trình phát triển cơ sở dữ liệu mới của bạn và xóa từ khóa “WITH” trong các phát triển hiện tại của bạn. Bạn có thể tìm thấy cách sử dụng gợi ý NOLOCK mà không có từ khóa “VỚI”.

 --- USER1 ---- BẮT ĐẦU CẬP NHẬT FruitSales SET SalesTotal =20 WHERE Id =2 WAITFOR DELAY '00:00:10'ROLLBACK TRANSACTIONSELECT * FROM FruitSales WHERE Id =2 --USER2 --- SELECT * FROM FruitSales (NOLOCK) WHERE Id =2 

Ngoài ra, gợi ý bảng READUNCOMMITTED tương đương với gợi ý NOLOCK và chúng ta có thể sử dụng gợi ý READUNCOMMITTED thay cho gợi ý NOLOCK.

 SELECT * FROM FruitSales (READUNCOMMITTED) WHERE Id =2 

Mặc dù vậy, vẫn có một trường hợp cụ thể về gợi ý NOLOCK không thể vượt qua rào cản khóa. Nếu có bất kỳ quy trình nào làm thay đổi bảng, gợi ý NOLOCK không thể vượt qua loại khóa này và không thể tiếp tục thao tác đọc. Lý do cho sự cố này là gợi ý NOLOCK có được khóa Sch-S (ổn định giản đồ) và câu lệnh ALTER TABLE có được khóa SCH-M (sửa đổi giản đồ), do đó, xung đột xảy ra.

Đầu tiên, chúng ta sẽ tìm hiểu bảng Object_Id của FruitSales với sự trợ giúp của truy vấn sau.

 chọn OBJECT_ID ('FruitSales') 

Chạy truy vấn user1 sau và sau đó chạy truy vấn user2. Do đó, truy vấn user2 sẽ trì hoãn việc hoàn thành quá trình thay đổi bảng user1.

 --USER1 --- BEGIN TRANALTER TABLE FruitSalesADD ColorofFruit varchar (200) WAITFOR DELAY '00:00:35GOCOMMIT TRAN --USER2 --- CHỌN * TỪ FruitSales (NOLOCK) WHERE Id =2 

Mở cửa sổ truy vấn mới và thực hiện truy vấn sau. Truy vấn này sẽ giúp tìm ra loại khóa của truy vấn user1 và user2.

 CHỌN Resource_type, Resource_database_id, Resource_description, Resource_associated_entity_id, Resource_lock_partition, Request_mode, Request_type, Request_status, Request_session_id, Request_request_id, Request_owner_type, Request_owner_id, Lockress_owner_adddddddddd673  

Bây giờ, chúng ta sẽ kiểm tra ma trận tương thích khóa cho tương tác SCH-M và SCH-S. Ma trận mô tả rằng tương tác SCH-M và SCH-S gây ra xung đột.

Kết luận

Trong bài viết này, chúng tôi đã đề cập đến quá trình đọc bẩn và gợi ý NOLOCK. Sử dụng gợi ý NOLOCK là một phương pháp hiệu quả để đọc một trang bị khóa nhưng nó cũng có một số ưu điểm và nhược điểm. Vì lý do này, bạn phải xem xét gợi ý NOLOCK trước khi sử dụng nó.

Tài liệu tham khảo

Hướng dẫn lập phiên bản hàng và khóa giao dịch máy chủ SQL

Gợi ý (Transact-SQL) - Bảng

ĐẶT MỨC ĐỘ CỰC KỲ GIAO DỊCH (Transact-SQL)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách kiểm tra mức độ tương thích của cơ sở dữ liệu trong SQL Server bằng T-SQL

  2. Cách xóa cột trong SQL Server bằng T-SQL

  3. Thêm mối quan hệ Khoá ngoại giữa hai Cơ sở dữ liệu

  4. Cách lấy hình ảnh nhị phân từ cơ sở dữ liệu bằng C # trong ASP.NET

  5. YEAR () Ví dụ trong SQL Server (T-SQL)