Tại sao nên sử dụng mức cách ly READ UNCOMMITTED?


225

Trong tiếng Anh đơn giản, những nhược điểm và lợi thế của việc sử dụng là gì

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

trong một truy vấn cho các ứng dụng .NET và các ứng dụng dịch vụ báo cáo?

Câu trả lời:


210

Mức cô lập này cho phép đọc bẩn. Một giao dịch có thể thấy những thay đổi không được cam kết thực hiện bởi một số giao dịch khác.

Để duy trì mức độ cô lập cao nhất, DBMS thường thu được các khóa trên dữ liệu, điều này có thể dẫn đến mất đồng thời và chi phí khóa cao. Mức cô lập này thư giãn tài sản này.

Bạn có thể muốn xem bài viết trên Wikipedia vềREAD UNCOMMITTED một vài ví dụ và đọc thêm.


Bạn cũng có thể quan tâm đến việc kiểm tra bài viết trên blog của Jeff Atwood về cách anh ấy và nhóm của anh ấy giải quyết vấn đề bế tắc trong những ngày đầu của Stack Overflow. Theo Jeff:

Nhưng có nolocknguy hiểm không? Bạn có thể kết thúc việc đọc dữ liệu không hợp lệ với read uncommitted? Vâng, trên lý thuyết. Bạn sẽ thấy không thiếu các phi hành gia kiến ​​trúc cơ sở dữ liệu, những người bắt đầu bỏ khoa học ACID về bạn và tất cả trừ kéo chuông báo cháy tòa nhà khi bạn nói với họ rằng bạn muốn thử nolock. Đó là sự thật: lý thuyết thật đáng sợ. Nhưng đây là những gì tôi nghĩ: "Về lý thuyết không có sự khác biệt giữa lý thuyết và thực hành. Trong thực tế có."

Tôi sẽ không bao giờ khuyên bạn nên sử dụng nolock như một cách tổng quát "tốt cho những gì bạn cảm thấy khó chịu" đối với bất kỳ vấn đề bế tắc cơ sở dữ liệu nào bạn có thể gặp phải. Bạn nên cố gắng chẩn đoán nguồn gốc của vấn đề trước.

Nhưng trong thực tế, việc thêm nolockvào các truy vấn mà bạn hoàn toàn biết là những việc đơn giản, đơn giản chỉ đọc dường như không bao giờ dẫn đến vấn đề ... Miễn là bạn biết bạn đang làm gì.

Một thay thế cho READ UNCOMMITTEDcấp độ mà bạn có thể muốn xem xét là READ COMMITTED SNAPSHOT. Trích dẫn Jeff một lần nữa:

Ảnh chụp nhanh dựa trên một phương pháp theo dõi thay đổi dữ liệu hoàn toàn mới ... không chỉ là một thay đổi logic nhỏ, nó yêu cầu máy chủ xử lý dữ liệu theo cách khác. Khi phương thức theo dõi thay đổi dữ liệu mới này được bật, nó sẽ tạo một bản sao hoặc ảnh chụp nhanh của mọi thay đổi dữ liệu. Bằng cách đọc các ảnh chụp nhanh này thay vì dữ liệu trực tiếp tại các thời điểm tranh chấp, Khóa chung không còn cần thiết cho việc đọc và hiệu suất cơ sở dữ liệu tổng thể có thể tăng.


13
Tác giả dường như ngụ ý rằng đọc không cam kết / không khóa sẽ trả về bất kỳ dữ liệu nào được cam kết lần cuối. Sự hiểu biết của tôi được đọc không được cam kết sẽ trả về bất kỳ giá trị nào được đặt cuối cùng ngay cả từ các giao dịch không được cam kết. Nếu vậy, kết quả sẽ không lấy được dữ liệu "một vài giây lỗi thời". Nó sẽ (hoặc ít nhất có thể nếu giao dịch ghi dữ liệu bạn đọc bị khôi phục) sẽ truy xuất dữ liệu không tồn tại hoặc không bao giờ được cam kết. Tôi có nhầm không?
xr280xr

4
Câu trả lời chính xác. BTW, Oracle đã "chụp nhanh" theo mặc định kể từ khi tôi biết điều đó, có lẽ là hàng thập kỷ trước khi Sql Server giới thiệu nó. Tôi đã khá thất vọng khi bắt đầu với SQL Server và tôi phát hiện ra rằng tất cả các vấn đề tương tranh đã được giải quyết bằng cách sử dụng các cơ chế khóa "nguyên thủy". Chưa bao giờ thấy "Đọc không cam kết" trong Oracle. Và người học viên cũng hạnh phúc như các phi hành gia.
Stefan Steinegger

13
READ UNCOMMITTEDcũng có thể khiến bạn đọc hàng hai lần hoặc bỏ lỡ toàn bộ hàng . Nếu việc phân chia trang xảy ra trong khi bạn đọc, thì bạn có thể bỏ lỡ toàn bộ khối dữ liệu. WITH(NOLOCK)chỉ nên được sử dụng nếu độ chính xác của kết quả không quan trọng
Ian Boyd

8
@DanielNolan, Kiến nghị điều đó là nguy hiểm vì Jeff không biết những gì ông đã làm . Đọc không phổ biến chỉ có ý nghĩa cho việc đọc dữ liệu sẽ không bao giờ được sửa đổi. Cố gắng sử dụng nó để đọc các bảng sẽ được viết để có nghĩa là trong thực tế bạn sẽ đọc một cái gì đó được cuộn lại. Không chỉ là bạn đang đọc dữ liệu cũ vài giây, mà là bạn .................................. ................... ........................... ....
Pacerier

5
................................... đang đọc dữ liệu thậm chí không bao giờ được cam kết. Đó là định nghĩa của việc đọc bị hỏng. Và nếu bạn định viết dựa trên kết quả của những lần đọc không được cam kết đó, thì thực tế bạn sẽ viết dữ liệu bị hỏng. Ngoài ra, bài báo nói rằng "MySQL, phát triển trên các ứng dụng web, ít bi quan hơn so với SQL Server". Không đúng, Sql Server hoạt động ở mức đọc được cam kết theo mặc định, trong khi MySQL hoạt động ở mức có thể lặp lại - đọc theo mặc định, cách năm lần đọc không được cam kết.
Pacerier

36

Điều này có thể hữu ích để xem tiến trình của các truy vấn chèn dài, thực hiện bất kỳ ước tính sơ bộ nào (như COUNT(*)hoặc thô SUM(*)), v.v.

Nói cách khác, kết quả mà các truy vấn đọc bẩn trả về là tốt miễn là bạn coi chúng là ước tính và không đưa ra bất kỳ quyết định quan trọng nào dựa trên chúng.


36

Trường hợp sử dụng yêu thích của tôi read uncommitedlà để gỡ lỗi một cái gì đó đang xảy ra trong một giao dịch.

Khởi động phần mềm của bạn dưới trình gỡ lỗi, trong khi bạn đang thực hiện các dòng mã, nó sẽ mở một giao dịch và sửa đổi cơ sở dữ liệu của bạn. Trong khi mã bị dừng, bạn có thể mở một bộ phân tích truy vấn, đặt ở mức cô lập không được đọc và thực hiện các truy vấn để xem những gì đang xảy ra.

Bạn cũng có thể sử dụng nó để xem các quy trình chạy dài có bị kẹt hoặc cập nhật chính xác cơ sở dữ liệu của bạn không.

Thật tuyệt nếu công ty của bạn thích làm các thủ tục lưu trữ quá phức tạp.


6
Công ty của tôi thích làm các thủ tục lưu trữ quá phức tạp. Thật là một ý tưởng tuyệt vời để khắc phục sự cố!
Brandon

22

Ưu điểm là nó có thể nhanh hơn trong một số tình huống. Nhược điểm là kết quả có thể sai (dữ liệu chưa được cam kết có thể được trả lại) và không có gì đảm bảo rằng kết quả có thể lặp lại.

Nếu bạn quan tâm đến độ chính xác, đừng sử dụng cái này.

Thêm thông tin về MSDN :

Thực hiện đọc bẩn, hoặc khóa cách ly 0, có nghĩa là không có khóa chia sẻ nào được ban hành và không có khóa độc quyền nào được vinh danh. Khi tùy chọn này được đặt, có thể đọc dữ liệu không được cam kết hoặc bẩn; các giá trị trong dữ liệu có thể được thay đổi và các hàng có thể xuất hiện hoặc biến mất trong tập dữ liệu trước khi kết thúc giao dịch. Tùy chọn này có tác dụng tương tự như đặt NOLOCK trên tất cả các bảng trong tất cả các câu lệnh CHỌN trong một giao dịch. Đây là hạn chế ít nhất trong bốn cấp độ cách ly.


Làm thế nào điều này sẽ ảnh hưởng đến tốc độ của truy vấn?
Kip Real

11
@Kip - các selectbáo cáo sẽ không phải chờ để có được các khóa được chia sẻ trên các tài nguyên bị khóa độc quyền bởi các giao dịch khác.
Jarrod Dixon

15

Khi nào thì dùng được READ UNCOMMITTED?

Nguyên tắc

Tốt : Báo cáo tổng hợp lớn hiển thị tổng số thay đổi liên tục.

Rủi ro : Gần như mọi thứ khác.

Tin tốt là phần lớn các báo cáo chỉ đọc thuộc danh mục Tốt đó.

Chi tiết hơn ...

Ok để sử dụng nó:

  • Gần như tất cả các báo cáo tổng hợp hướng tới người dùng cho dữ liệu hiện tại, không tĩnh, ví dụ như doanh số hàng năm. Nó có nguy cơ sai số (có thể <0,1%) thấp hơn nhiều so với các yếu tố không chắc chắn khác như lỗi nhập liệu hoặc chỉ là sự ngẫu nhiên khi dữ liệu chính xác được ghi lại từng phút.

Điều đó có thể bao gồm phần lớn những gì một bộ phận Kinh doanh thông minh sẽ làm, nói, SSRS. Tất nhiên, ngoại lệ, là bất cứ thứ gì có dấu $ ở phía trước nó. Nhiều người chiếm tiền với sự nhiệt tình hơn nhiều so với việc áp dụng cho các số liệu cốt lõi liên quan cần có để phục vụ khách hàng và tạo ra số tiền đó. (Tôi đổ lỗi cho kế toán).

Khi rủi ro

  • Bất kỳ báo cáo đi xuống mức chi tiết. Nếu chi tiết đó là bắt buộc, nó thường ngụ ý rằng mỗi hàng sẽ có liên quan đến một quyết định. Trong thực tế, nếu bạn không thể kéo một tập hợp con nhỏ mà không chặn thì đó có thể là lý do chính đáng để nó hiện đang được chỉnh sửa.

  • Dữ liệu lịch sử. Nó hiếm khi tạo ra sự khác biệt thực tế nhưng trong khi người dùng hiểu dữ liệu thay đổi liên tục không thể hoàn hảo, họ không cảm thấy giống nhau về dữ liệu tĩnh. Đọc bẩn sẽ không bị tổn thương ở đây nhưng đôi khi đọc có thể được. Xem như bạn không nên có khối trên dữ liệu tĩnh nào, tại sao lại mạo hiểm?

  • Gần như bất cứ thứ gì cung cấp cho ứng dụng cũng có khả năng ghi.

Khi thậm chí kịch bản OK không ổn.

  • Có bất kỳ ứng dụng hoặc quá trình cập nhật nào sử dụng các giao dịch lớn không? Những người gỡ bỏ sau đó chèn lại rất nhiều hồ sơ bạn đang báo cáo? Trong trường hợp đó, bạn thực sự không thể sử dụng NOLOCKtrên các bảng đó cho bất cứ điều gì.

Điểm tốt về báo cáo. Trên thực tế, ý tưởng đầu tiên xuất hiện trong đầu tôi là liệu tôi có nên sử dụng read uncommittedcho các ứng dụng web hay không khi người dùng nhìn thấy một số lưới UI trong đó độ chính xác của dữ liệu không quá quan trọng. Người dùng chỉ muốn có một cái nhìn tổng quan nhanh về những bản ghi có thể có ở đó và có thể với một số phân trang, sắp xếp & lọc. Chỉ khi người dùng nhấp vào nút Chỉnh sửa, thì tôi mới cố gắng đọc bản ghi mới nhất với mức cô lập nghiêm ngặt hơn. Không nên tiếp cận như vậy tốt hơn về mặt hiệu suất?
JustAMartin

Vâng, tôi nghĩ đó là hợp lý. Hãy nhớ rằng vấn đề quan trọng hơn là đảm bảo rằng dữ liệu đã không bị người khác thay đổi giữa thời điểm nhấn nút chỉnh sửa và thời điểm gửi. Bạn có thể xử lý điều đó bằng cách bắt đầu một giao dịch tìm nạp dữ liệu như thế nào select item from things with (UPDLOCK). Đặt thời gian chờ nhanh vào đó để nếu nó không thể có được khóa nhanh, nó sẽ báo cho người dùng biết nó đang được chỉnh sửa. Điều đó sẽ giữ cho bạn an toàn không chỉ từ người dùng mà cả các nhà phát triển. Vấn đề duy nhất ở đây là bạn phải bắt đầu suy nghĩ về thời gian chờ và cách bạn xử lý vấn đề đó trong UI.
Adamantish

6

Về báo cáo, chúng tôi sử dụng nó trên tất cả các truy vấn báo cáo của mình để ngăn truy vấn làm chậm cơ sở dữ liệu. Chúng tôi có thể làm điều đó bởi vì chúng tôi đang kéo dữ liệu lịch sử, chứ không phải dữ liệu tối đa.


4

Sử dụng READ_UNCOMMITTED trong trường hợp nguồn rất khó thay đổi.

  • Khi đọc dữ liệu lịch sử. ví dụ: một số nhật ký triển khai đã xảy ra hai ngày trước.
  • Khi đọc siêu dữ liệu một lần nữa. ví dụ ứng dụng dựa trên siêu dữ liệu.

Không sử dụng READ_UNCOMMITTED khi bạn biết souce có thể thay đổi trong quá trình tìm nạp.


1
Tôi cảm thấy ngược lại áp dụng. Đầu tiên dữ liệu tĩnh nên được đọc tốt không có khối. Nếu nó không chặn thì bây giờ bạn đã phát hiện ra có một vấn đề giao dịch treo quan trọng để sửa chữa. Ngoài ra, người dùng sẽ mong đợi điều này khớp với vị trí thập phân cuối cùng bất cứ điều gì họ in ra cho báo cáo thường niên năm ngoái. Họ thường không mong đợi cùng một báo cáo mà họ biết là liên tục thay đổi. Điều này không áp dụng cho báo cáo tài chính chi tiết, cực kỳ nhạy cảm với thời gian nhưng nếu 1 lỗi nhập vào 1000 có thể chấp nhận được thì cũng vậy READ UNCOMMITTED.
Adamantish

TLDR: Nếu dữ liệu sẽ không thay đổi, bạn không cần ĐỌC HIỂU vì dù sao cũng không có khối nào. Nếu bạn sai và nó thay đổi thì thật tốt khi bạn chặn người dùng nhận dữ liệu bẩn hơn dự kiến.
Adamantish

Có, tôi có xu hướng đồng ý với @Adamantish ở đây - bạn có thể hưởng lợi từ READ UNCOMMITTEDhầu hết các tình huống khi dữ liệu của bạn đang được sử dụng tích cực và bạn muốn giảm tải trên máy chủ để tránh các bế tắc có thể xảy ra và quay vòng giao dịch chỉ vì một số người dùng bất cẩn lạm dụng " Làm mới nút "trong một trang web với một bảng dữ liệu. Người dùng xem một loạt các bản ghi cùng một lúc, thường không quan tâm nhiều nếu dữ liệu hơi lỗi thời hoặc được cập nhật một phần. Chỉ khi người dùng chuẩn bị chỉnh sửa bản ghi, thì bạn mới có thể cung cấp cho anh ấy / cô ấy dữ liệu chính xác nhất.
JustAMartin

2

Điều này sẽ cung cấp cho bạn đọc bẩn và hiển thị cho bạn các giao dịch chưa được cam kết. Đó là câu trả lời rõ ràng nhất. Tôi không nghĩ rằng đó là một ý tưởng tốt để sử dụng điều này chỉ để tăng tốc độ đọc của bạn. Có nhiều cách khác để làm điều đó nếu bạn sử dụng một thiết kế cơ sở dữ liệu tốt.

Nó cũng thú vị để lưu ý những gì không xảy ra. ĐỌC UNCOMMITTED không chỉ bỏ qua các khóa bảng khác. Nó cũng không gây ra bất kỳ ổ khóa nào.

Hãy xem xét bạn đang tạo một báo cáo lớn hoặc bạn đang di chuyển dữ liệu ra khỏi cơ sở dữ liệu của mình bằng cách sử dụng câu lệnh CHỌN lớn và có thể phức tạp. Điều này sẽ khiến khóa được chia sẻ có thể được chuyển thành khóa bảng chung trong suốt thời gian giao dịch của bạn. Các giao dịch khác có thể đọc từ bảng, nhưng cập nhật là không thể. Đây có thể là một ý tưởng tồi nếu cơ sở dữ liệu sản xuất của nó kể từ khi sản xuất có thể dừng hoàn toàn.

Nếu bạn đang sử dụng READ UNCOMMITTED, bạn sẽ không đặt khóa chia sẻ trên bàn. Bạn có thể nhận được kết quả từ một số giao dịch mới hoặc bạn có thể không phụ thuộc vào nơi mà dữ liệu được chèn vào và thời gian giao dịch CHỌN của bạn đã đọc. Bạn cũng có thể nhận được cùng một dữ liệu hai lần nếu ví dụ phân tách trang xảy ra (dữ liệu sẽ được sao chép sang một vị trí khác trong tệp dữ liệu).

Vì vậy, nếu dữ liệu rất quan trọng đối với bạn rằng dữ liệu có thể được chèn trong khi thực hiện CHỌN, thì ĐỌC KHÔNG HOÀN THÀNH có thể có ý nghĩa. Bạn phải xem xét rằng báo cáo của bạn có thể có một số lỗi, nhưng nếu nó dựa trên hàng triệu hàng và chỉ một vài trong số chúng được cập nhật trong khi chọn kết quả thì điều này có thể "đủ tốt". Giao dịch của bạn cũng có thể thất bại tất cả cùng nhau vì tính duy nhất của một hàng có thể không được đảm bảo.

Một cách tốt hơn hoàn toàn có thể là sử dụng SNAPSHOT ISOLATION LEVEL nhưng các ứng dụng của bạn có thể cần một số điều chỉnh để sử dụng điều này. Một ví dụ về điều này là nếu ứng dụng của bạn có một khóa độc quyền trên một hàng để ngăn người khác đọc nó và chuyển sang chế độ chỉnh sửa trong UI. SNAPSHOT ISOLATION LEVEL cũng đi kèm với một hình phạt hiệu suất đáng kể (đặc biệt là trên đĩa). Nhưng bạn có thể khắc phục điều đó bằng cách ném phần cứng vào vấn đề. :)

Bạn cũng có thể xem xét khôi phục bản sao lưu cơ sở dữ liệu để sử dụng để báo cáo hoặc tải dữ liệu vào kho dữ liệu.


0

Nó có thể được sử dụng cho một bảng đơn giản, ví dụ như trong bảng kiểm toán chỉ chèn, trong đó không có cập nhật cho hàng hiện có và không có fk cho bảng khác. Chèn là một chèn đơn giản, không có hoặc có ít cơ hội quay trở lại.


-7

Tôi luôn luôn sử dụng READ UNCOMMITTED ngay bây giờ. Nó nhanh với các vấn đề ít nhất. Khi sử dụng các cách ly khác, bạn sẽ hầu như luôn gặp phải một số vấn đề Chặn.

Miễn là bạn sử dụng các trường Tăng tự động và chú ý hơn một chút đến các phần chèn thì tiền phạt của bạn và bạn có thể nói lời tạm biệt với các vấn đề chặn.

Bạn có thể mắc lỗi với READ UNCOMMITED nhưng thành thật mà nói, rất dễ dàng để đảm bảo các phần chèn của bạn là bằng chứng đầy đủ. Chèn / Cập nhật sử dụng kết quả từ một lựa chọn là điều duy nhất bạn cần để ý. (Sử dụng READ CAM KẾT tại đây hoặc đảm bảo rằng việc đọc bẩn sẽ không gây ra sự cố)

Vì vậy, hãy đọc Dirty Reads (Đặc biệt cho các báo cáo lớn), phần mềm của bạn sẽ chạy mượt hơn ...


6
Điều này rất không chính xác và chỉ chạm vào bề mặt của các vấn đề có thể xảy ra với nolock. Các trang có thể phân tách, tham gia có thể thất bại, bạn có thể đọc dữ liệu không tồn tại hoặc dữ liệu trùng lặp. Không có cách nào để sử dụng nó hoàn hảo: bạn không thể tin tưởng vào độ chính xác của bất cứ thứ gì dưới mức cô lập này. ĐỌC SNAPSHOT là một "thuốc chữa bách bệnh giả" ít nguy hiểm hơn
Mark Sowul

@MarkSowul Việc hạ thấp câu trả lời này có vẻ không công bằng với tôi. @Clive đã rõ ràng rằng anh ấy sẽ chuyển sang Committedchèn và cập nhật. Đối với các vấn đề khác, ông cũng thể hiện nhận thức về các vấn đề phân chia trang khi đề cập đến việc sử dụng khóa tăng tự động. Tôi đồng ý với anh ta rằng gần như tất cả các báo cáo trực tiếp được thực hiện để chỉ đọc bởi một con người có thể chấp nhận sự khác biệt nhỏ ở vị trí thập phân cuối cùng. Tôi đồng ý rằng đó là một câu chuyện khác nhau cho các danh sách chi tiết hoặc dữ liệu được định sẵn để đọc và chuyển đổi máy và Clive cũng vậy.
Adamantish

1
Nhận xét này cũng cho thấy sự thiếu hiểu biết đầy đủ về các vấn đề có thể xảy ra với nolock. "Sự khác biệt nhỏ ở vị trí thập phân cuối cùng" hầu như không bao gồm nó. Ngay cả việc chạm vào "chỉ sử dụng đọc cam kết để chèn / cập nhật" cũng là sai như lời khuyên chung (nếu nó "chèn bản ghi nếu nó không tồn tại" thì sao?). Trong mọi trường hợp, "[đọc không cam kết] là nhanh với ít vấn đề nhất" là sai về mặt phân loại.
Mark Sowul

Đối với hồ sơ, tôi đồng ý với câu trả lời của bạn, Adamantish: tổng hợp gần như chính xác và ít khác.
Mark Sowul
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.