Jaka jest różnica między SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED a Query Hint NOLOCK?

20-lut-2011

Na poziomie połączenia z serwerem SQL można zadeklarować tzw. Transaction Isolation Level. Zależnie od wybranego poziomu transakcje dokonują blokad przy odczycie rekordów lub nie i czytając uwzględniają albo ignorują inne nałożone na rekordy blokady.

Najsłabszym poziomem izolacji transakcji jest READ UNCOMMITTED. Jeżeli w swoim skrypcie na początku zapiszesz:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO

to twoje SELECT-y będą widziały dane zapisane przez inne jeszcze niezakończone transakcje. Jeżeli pracowałbyś na domyślnym poziomie izolacji transakcji READ COMMITTED, to twój SELECT zatrzyma się o ile będzie chciał przeczytać rekord zmodyfikowany przez inną nie zatwierdzoną transakcję.

Bardzo podobnie działa query hint NOLOCK. On również pozwala na odczytanie niezatwierdzonych zmian.

Jaka jest wobec tego różnica między NOLOCK, a izolacją READ UNCOMMITTED?

Otóż jeżeli użyłeś poziomu izolacji READ UNCOMMITTED, to WSZYSTKIE od tej powy wykonywane odczyty z bazy danych nie używają blokad i czytają niezatwierdzone cudze transakcje. Aby zakończyć takie działanie musisz się przełączyć na inny poziom transakcji izolacji, co zresztą nie jest trudne bo wystarczy wydać komendę:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
GO

Jeżeli wolałbyś pracować cały czas na innym poziomie izolacji, ale na chwilę w jednym zapytaniu skorzystać z „brudnego odczytu” niezatwierdzonych transakcji, możesz użyć query hint do tej transakcji:

SELECT *
       FROM Production.Product as p WITH (NOLOCK)
           JOIN Production.ProductReview pr
          ON pr.productid=p.ProductID

Zauważ, że w powyższym zapytaniu odczyt niezakończonych transakcji dotyczy tylko jednej (!) tabeli. Gdybyś użył transaction  isolation level READ UNCOMMITTED, to brudny odczyt dotyczył by obu tabel.

A ogólnie rzecz biorąc, zawsze lepiej poszukać, dlaczego dochodzi do blokad i usunąć ich przyczynę niż stosować brak blokad.

Komentarze:

  1. Mobilo » Blog Archive » Jak działa TRANSACTION ISOLATION LEVEL SERIALIZABLE? napisał,

    […] Jaka jest różnica między SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED a Query Hint NOLOCK? […]

  2. Mobilo » Blog Archive » Opcja set XACT_ABORT ON lub OFF napisał,

    […] SET TRANSACTION ISOLATION LEVEL […]

Autor: Rafał Kraik