ALLOW_SNAPSHOT_ISOLATION và READ_COMMITTED_SNAPSHOT


38

Hầu hết các diễn đàn và ví dụ trực tuyến luôn đề nghị có cả hai ALLOW_SNAPSHOT_ISOLATIONREAD_COMMITTED_SNAPSHOTđược đặt thành BẬT mỗi khi ai đó hỏi ảnh chụp nhanh, phiên bản hàng hoặc câu hỏi tương tự.

Tôi đoán từ SNAPSHOT trong cả hai cài đặt có một chút khó hiểu. Tôi nghĩ rằng, để cho cơ sở dữ liệu để sử dụng hàng versioning thay ổ khóa cho hành vi mặc định READ_COMMITTED, cơ sở dữ liệu READ_COMMITTED_SNAPSHOTđược thiết lập để ON bất kể những gì ALLOW_SNAPSHOT_ISOLATIONthiết lập.

Các ALLOW_SNAPSHOT_ISOLATIONthiết lập được thiết lập để ON chỉ cho phép cô lập bản chụp khi bắt đầu một giao dịch (ví dụ SET GIAO DỊCH cô lập CẤP SNAPSHOT) bất kể các READ_COMMITTED_SNAPSHOTthiết lập.

Lý do duy nhất để đặt hai cài đặt này thành BẬT là khi nó cần phải cách ly phiên bản hàng ĐỌC .

Câu hỏi của tôi là, sự hiểu biết của tôi không chính xác theo một cách nào đó? Và rằng hai cài đặt này phải luôn được đặt thành BẬT cùng nhau (đặc biệt đối với phiên bản hàng ĐỌC CAM KẾT)?

Câu trả lời:


25

Sự am hiểu của bạn đa đung đăn. Nó có một chút bối rối.

Kim Tripp (một trong những lập trình viên của SQL Server và là một phần không thể thiếu của SQLSkills) trải qua chính xác những gì bạn đã nêu trong video MCM trên Snapshot Isolation . Nhanh chóng fwd đến 41:45 trong video để đến phần cô ấy trả lời câu hỏi của bạn.

Nếu bạn sử dụng ALLOW_SNAPSHOT_ISOLATIONhãy chắc chắn rằng bạn sử dụng SET TRANSACTION ISOLATION LEVEL SNAPSHOTmã của mình, nếu không bạn sẽ không nhận được bất kỳ lợi ích nào.

Nếu bạn đặt SET READ_COMMITTED_SNAPSHOT ON, thì không cần phải sửa đổi bất kỳ mã nào. MS SQL Server tự động áp dụng cách ly ảnh chụp nhanh cho bảng đó.

Tôi đã không kiểm tra xem điều gì sẽ xảy ra nếu bạn yêu cầu một mức cô lập khác trong mã của bạn, tôi nghi ngờ nó sẽ ghi đè tùy chọn này nhưng trước tiên hãy kiểm tra nó.

Một cái nhìn nhanh về chi phí hoạt động bằng cách sử dụng Snapshot Isolation.

Bài viết hay về cách cô lập ảnh chụp nhanh có thể thay đổi hành vi dự kiến ​​của ứng dụng của bạn . Nó cho thấy các ví dụ về cách một câu lệnh cập nhật và câu lệnh chọn có thể trả về kết quả hoàn toàn khác nhau và bất ngờ.


Cảm ơn các liên kết. Giống như các BOL khác, cô ấy đã thảo luận hai thiết lập này một cách độc lập và tập thể (đó là nơi nó hơi khó hiểu, hoặc có lẽ tôi nghĩ quá nhiều về nó). Tôi đã phải kiểm tra nó để hiểu rõ hơn.
Travis

4
Đây là một câu trả lời tuyệt vời và tôi chỉ muốn làm rõ một vài mục. Đầu tiên, nếu bạn chỉ quét video, hãy bắt đầu lúc 23:18 cũng như 41:45. Thời gian đầu thêm chi tiết. Mặc dù Kim đề cập một câu trả lời cho câu hỏi ban đầu, vẫn cần phải sửa đổi mã nếu sử dụng cả hai. Read_Commned_Snapshot là cách ly mức câu lệnh, nói cách khác chỉ áp dụng cho câu lệnh hiện đang chạy. Allow_Snapshot_Isolation là sự cô lập ở cấp độ giao dịch, mọi thứ nằm giữa Begin Tran và Commit. Chúng có thể được tham gia một cách riêng biệt, nhưng cùng một chi phí 14 byte cho mỗi hàng được thiết lập.
Delux

cảm ơn bạn đã thêm các chi tiết bổ sung về chi phí 14 byte được thiết lập. Kim đi xuyên qua nó trong video nhưng cũng rất hữu ích khi có nó ở đây trong văn bản.
Ali Razeghi

15

OK, trở về nhà và thử nghiệm. Đây là sự quan sát.

CREATE DATABASE TEST;
GO
CREATE TABLE TABLE1
(
    ID tinyint,
    Details varchar(10)
);
GO
INSERT INTO TABLE1
VALUES (1, 'Original');
GO

SELECT
    name,
    snapshot_isolation_state_desc,
    is_read_committed_snapshot_on
FROM sys.databases
WHERE name = 'TEST';
GO

Thử nghiệm đầu tiên với cả hai cài đặt được xác nhận là TẮT.

Truy vấn 1

USE TEST;

BEGIN TRAN
UPDATE TABLE1
SET Details = 'Update'
WHERE ID = 1;

--COMMIT;
--ROLLBACK;
GO

Truy vấn 2

USE TEST;

SELECT ID, Details
FROM TABLE1
WHERE ID = 1;
GO

Trong thử nghiệm này, truy vấn 2 đang chờ truy vấn 1 để xác nhận, dm_tran_locks DMV cho thấy khóa độc quyền trên TABLE1 phát sinh bởi truy vấn 1.

USE TEST;

SELECT
    DB_NAME(tl.resource_database_id) AS DBName,
    resource_type,
    OBJECT_NAME(resource_associated_entity_id) AS tbl_name,
    request_mode,
    request_status,
    request_session_id
FROM sys.dm_tran_locks tl
WHERE 
    resource_database_id = db_id('TEST')
    AND resource_type = 'OBJECT'

Thử nghiệm thứ hai , phục hồi giao dịch trước đó, đặt READ_COMMITTED_SNAPSHOT BẬT nhưng để ALLOW_SNAPSHOT_ISOLATION TẮT.

ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT ON
WITH ROLLBACK IMMEDIATE;
GO

Chạy Truy vấn 1 và chạy truy vấn 2. DMV hiển thị truy vấn 1 phải chịu khóa độc quyền, nhưng truy vấn 2 trả về chi tiết với 'Bản gốc' mà không truy vấn 1 cam kết giao dịch. Có vẻ như phiên bản hàng READ_COMMITTED đã được đưa ra.

Thêm SET TRANSACTION ISOLATION LEVEL SNAPSHOT;vào truy vấn 1 và truy vấn 2 và chạy truy vấn 1 hoặc truy vấn 2 trả về lỗi - Giao dịch cách ly ảnh chụp không thành công khi truy cập cơ sở dữ liệu 'TEST' vì không cho phép cách ly ảnh chụp nhanh trong cơ sở dữ liệu này. Sử dụng ALTER DATABASE để cho phép cách ly ảnh chụp nhanh.

Thử nghiệm thứ ba , phục hồi giao dịch trước đó. Đặt READ_COMMITTED_SNAPSHOT TẮT và ALLOW_SNAPSHOT_ISOLATION BẬT.

ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT OFF
WITH ROLLBACK IMMEDIATE;
GO

ALTER DATABASE TEST
SET ALLOW_SNAPSHOT_ISOLATION ON;
GO

Chạy truy vấn 1, rồi truy vấn 2. DMV hiển thị khóa độc quyền phát sinh bởi truy vấn 1. Truy vấn 2 dường như đang chờ truy vấn 1 hoàn tất. Bật ALLOW_SNAPSHOT_ISOLATION ON không xuất hiện để bật phiên bản hàng ĐỌC.

Thêm SET TRANSACTION ISOLATION LEVEL SNAPSHOT;vào cả truy vấn 1 và truy vấn 2. Chạy truy vấn 1 và sau đó truy vấn 2. Trong khi DMV hiển thị truy vấn 1 phải chịu khóa độc quyền, truy vấn 2 trả về chi tiết với 'Bản gốc'. Ảnh chụp cách ly dường như được đặt ra.

Quan sát từ thử nghiệm cho thấy rằng READ_COMMITTED_SNAPSHOTchính nó kích hoạt / vô hiệu hóa phiên bản hàng READ CAMITTED bất kể ALLOW_SNAPSHOT_ISOLATIONcài đặt và ngược lại.


4

Sự am hiểu của bạn đa đung đăn. Tôi thích định nghĩa ngắn gọn, sạch sẽ và đơn giản từ đây :

Khi tùy chọn cơ sở dữ liệu READ_COMMITTED_SNAPSHOT ở trạng thái BẬT, các giao dịch sẽ đặt mức cô lập đã đọc cam kết sử dụng phiên bản hàng.

Khi tùy chọn cơ sở dữ liệu ALLOW_SNAPSHOT_ISOLATION được BẬT, các giao dịch có thể đặt mức cô lập ảnh chụp nhanh.

Có vẻ như rất nhiều sự hiểu lầm đến từ chính MS. Ví dụ, ở đây họ nói:

Nếu bạn đặt tùy chọn cơ sở dữ liệu READ_COMMITTED_SNAPSHOT thành BẬT, công cụ cơ sở dữ liệu sẽ sử dụng phiên bản hàng và cách ly ảnh chụp làm mặc định, thay vì sử dụng khóa để bảo vệ dữ liệu.

Nhưng "cách ly ảnh chụp" được đề cập không bằng hành vi giao dịch set transaction isolation level snapshotđược áp dụng.

Đối với sự khác biệt, giải thích tốt đẹp là ở đây .

Có lẽ sẽ tốt hơn nếu READ_COMMITTED_SNAPSHOT được đặt tên là READ_COMMITTED_law_VERSIONING hoặc đại loại như thế. :)


0

Tôi thích tóm tắt này từ Microsoft :

Đặt tùy chọn READ_COMMITTED_SNAPSHOT ON cho phép truy cập vào các hàng được phiên bản theo mức cách ly READ CAMITTED mặc định. Nếu tùy chọn READ_COMMITTED_SNAPSHOT được đặt thành TẮT, bạn phải đặt rõ ràng mức cách ly Ảnh chụp cho mỗi phiên để truy cập các hàng được phiên bản.

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.