Tôi nghĩ rằng các mức cô lập ở trên là như nhau. Ai đó có thể vui lòng mô tả với một số ví dụ tốt đẹp sự khác biệt chính là gì?
Tôi nghĩ rằng các mức cô lập ở trên là như nhau. Ai đó có thể vui lòng mô tả với một số ví dụ tốt đẹp sự khác biệt chính là gì?
Câu trả lời:
Đọc cam kết là một mức cô lập đảm bảo rằng mọi dữ liệu đã đọc được cam kết tại thời điểm này được đọc. Nó chỉ đơn giản là hạn chế người đọc nhìn thấy bất kỳ đọc trung gian, không cam kết, 'bẩn'. Không có gì hứa hẹn rằng nếu giao dịch phát hành lại việc đọc, sẽ tìm thấy cùng một dữ liệu, dữ liệu có thể tự do thay đổi sau khi được đọc.
Đọc lặp lại là mức cô lập cao hơn, ngoài các đảm bảo của mức đã đọc cam kết, nó cũng đảm bảo rằng mọi dữ liệu đọc không thể thay đổi , nếu giao dịch đọc lại cùng một dữ liệu, nó sẽ tìm thấy dữ liệu đã đọc trước đó, không thay đổi , và có sẵn để đọc.
Mức cô lập tiếp theo, tuần tự hóa, đảm bảo thậm chí còn mạnh mẽ hơn: ngoài tất cả mọi thứ đảm bảo đọc lặp lại, nó cũng đảm bảo rằng không có dữ liệu mới nào có thể được nhìn thấy bằng lần đọc tiếp theo.
Giả sử bạn có một bảng T có cột C có một hàng trong đó, giả sử nó có giá trị '1'. Và xem xét bạn có một nhiệm vụ đơn giản như sau:
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;
Đó là một nhiệm vụ đơn giản phát hành hai lần đọc từ bảng T, với độ trễ là 1 phút giữa chúng.
Nếu bạn tuân theo logic ở trên, bạn có thể nhanh chóng nhận ra rằng các giao dịch SERIALIZABLE, trong khi chúng có thể giúp bạn dễ dàng hơn, luôn chặn hoàn toàn mọi hoạt động đồng thời có thể, vì chúng yêu cầu không ai có thể sửa đổi, xóa cũng như chèn bất kỳ hàng nào. Mức cô lập giao dịch mặc định của System.Transactions
phạm vi .Net là tuần tự hóa và điều này thường giải thích hiệu suất kinh khủng dẫn đến kết quả.
Và cuối cùng, cũng có mức cô lập SNAPSHOT. Mức cô lập SNAPSHOT thực hiện các đảm bảo tương tự như tuần tự hóa, nhưng không phải bằng cách yêu cầu rằng không có giao dịch đồng thời nào có thể sửa đổi dữ liệu. Thay vào đó, nó buộc mọi người đọc phải xem phiên bản thế giới của riêng mình (đó là 'ảnh chụp nhanh'). Điều này làm cho nó rất dễ dàng để lập trình cũng như rất có thể mở rộng vì nó không chặn các cập nhật đồng thời. Tuy nhiên, lợi ích đó đi kèm với một mức giá: tiêu thụ tài nguyên máy chủ thêm.
Bổ sung đọc:
Trạng thái của cơ sở dữ liệu được duy trì từ khi bắt đầu giao dịch. Nếu bạn truy xuất một giá trị trong session1, sau đó cập nhật giá trị đó trong session2, lấy lại nó trong session1 sẽ trả về kết quả tương tự. Đọc được lặp lại.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
Trong bối cảnh giao dịch, bạn sẽ luôn lấy giá trị được cam kết gần đây nhất. Nếu bạn truy xuất một giá trị trong session1, hãy cập nhật nó trong session2, sau đó lấy nó trong session1again, bạn sẽ nhận được giá trị như được sửa đổi trong session2. Nó đọc hàng cam kết cuối cùng.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Bob
Có ý nghĩa?
Đơn giản chỉ là câu trả lời theo cách đọc và hiểu của tôi đối với chủ đề này và câu trả lời @ remus-rusanu dựa trên kịch bản đơn giản này:
Có hai quy trình A và B. Quy trình B đang đọc Bảng X Quy trình A đang viết trong bảng X Quy trình B đang đọc lại Bảng X.
Câu hỏi cũ đã có câu trả lời được chấp nhận, nhưng tôi muốn nghĩ về hai mức cô lập này về cách chúng thay đổi hành vi khóa trong SQL Server. Điều này có thể hữu ích cho những người đang gỡ lỗi bế tắc như tôi.
ĐỌC CAM KẾT (mặc định)
Các khóa được chia sẻ được lấy trong SELECT và sau đó được giải phóng khi câu lệnh SELECT hoàn thành . Đây là cách hệ thống có thể đảm bảo rằng không có dữ liệu bẩn đọc dữ liệu không được cam kết. Các giao dịch khác vẫn có thể thay đổi các hàng bên dưới sau khi CHỌN của bạn hoàn thành và trước khi giao dịch của bạn hoàn tất.
ĐỌC
Khóa chia sẻ được lấy trong CHỌN và sau đó chỉ được phát hành sau khi giao dịch hoàn tất . Đây là cách hệ thống có thể đảm bảo rằng các giá trị bạn đọc sẽ không thay đổi trong quá trình giao dịch (vì chúng vẫn bị khóa cho đến khi giao dịch kết thúc).
Cố gắng giải thích nghi ngờ này bằng các sơ đồ đơn giản.
Đọc cam kết: Ở đây trong mức cô lập này, Giao dịch T1 sẽ được đọc giá trị cập nhật của X được giao dịch bởi Giao dịch T2.
Đọc lại: Trong mức cô lập này, Giao dịch T1 sẽ không xem xét các thay đổi được cam kết bởi Giao dịch T2.
Tôi nghĩ rằng hình ảnh này cũng có thể hữu ích, nó giúp tôi làm tài liệu tham khảo khi tôi muốn nhanh chóng ghi nhớ sự khác biệt giữa các mức độ cô lập (nhờ kudvenkat trên youtube)
Xin lưu ý rằng, việc lặp lại trong lần đọc lặp lại liên quan đến một tuple, nhưng không phải cho toàn bộ bảng. Trong các mức cô lập ANSC, có thể xảy ra dị thường đọc ảo , có nghĩa là đọc một bảng có cùng mệnh đề hai lần có thể trả về các tập kết quả khác nhau trả về khác nhau. Theo nghĩa đen, nó không lặp lại .
Quan sát của tôi về giải pháp được chấp nhận ban đầu.
Trong RR (mysql mặc định) - Nếu một tx được mở và CHỌN đã được kích hoạt, một tx khác KHÔNG thể xóa bất kỳ hàng nào thuộc tập kết quả READ trước đó cho đến khi tx trước đó được thực hiện (trên thực tế, câu lệnh xóa trong tx mới sẽ bị treo) , tuy nhiên tx tiếp theo có thể xóa tất cả các hàng khỏi bảng mà không gặp sự cố nào. Btw, một READ tiếp theo trong tx trước đó vẫn sẽ thấy dữ liệu cũ cho đến khi nó được cam kết.