Table hint: TABLOCKX, HOLDLOCK, READPAST

12-mar-2011

Jeżeli zamierzasz wykonać procedurę składowaną pobierającą określone dane z jednej chwili, nie dopuszczając takiej opcji, że podczas wykonywania procedury ktoś dopisał/usunął czy też zmienił jakiś rekord możesz posłużyć się table hint TABLOCKX.

Poniższe zapytanie przed wykonaniem nałoży na tabelę blokadę na wyłączność. Skoro będzie blokada na wyłączność, to nikt nie może w tym czasie niczego zminiać. Wynik takiego zapytania na daną chwilę będzie więc jednoznaczny.

SELECT p.Size, AVG(p.ListPrice)  
FROM Production.Product AS p WITH (TABLOCKX)
WHERE p.Color='Red'
GROUP BY p.Size

TablockX blokuje tabelę, aż do zakończenia transakcji, w której znalazł się SELECT (sprawdzone)

Wskazówka zawierająca table hint znajduje się zawsze za nazwą tabeli (po aliasie, jeżeli go użyłeś). Wskazówki można ze sobą łączyć:

SELECT p.Size, AVG(p.ListPrice)  
FROM Production.Product AS p WITH (TABLOCKX, HOLDLOCK)
WHERE p.Color='Red'
GROUP BY p.Size

Nieco dziwnym hintem jest READPAST, który powoduje, że zapytanie opuszcza sobie rekordy zablokowane przez inne transakcje! Tak! Opuszcza sobie! Rozważ taki przykład:

Pierwsze okienko query:

SELECT * 
FROM Production.Product AS p WITH (READPAST)
WHERE p.ProductID in (1,2,3,4)

Zostały zwrócone 4 rekordy.

A teraz drugie okienko query:

BEGIN TRANSACTION
UPDATE  PRODUCTION.Product
SET Name='1111'
WHERE ProductID=3

Ta transakcja się jeszcze nie skończyła, więc rekord nr 3 ma blokadę na wyłączność

Wracamy do pierwszego okienka i ponawiamy zapytanie:

SELECT * 
FROM Production.Product AS p WITH (READPAST)
WHERE p.ProductID in (1,2,3,4)

 W wyniku otrzymujemy 3 rekordy:

Można by powiedzieć „i jak tu zaufać takiemu zapytaniu”. Możesz je wykorzystać jeżeli chcesz „na szybko”, „mniej więcej” sprawdzić zawartość tabel. Ale wypłaty na podstawie takiego zapytania nie chciałbym otrzymać…

Komentarze są wyłączone

Autor: Rafał Kraik