
---Edited---
... trochę poszperałem, poprzeglądałem internet od tego czasu, bylem w empiku i niestety nie mieli na stanie tej książki

W kwestii wyjaśnienia: wszystkie informacje przeze mnie prezentowane, są pobrane z kopii rozmowy z Markiem Adamczukiem z http://mssqlserver.org.pl, adres do topicu znajduje się tutaj (niestety aby przeglądać to forum trzeba się zarejestrować), jeśli ktoś będzie szukał dodatkowych informacji proponuję zajrzeć do Microsoft SQL Server BOL można pobrać stąd (cenne źródło informacji na temat SQL Server 2000 i msde 2000).
Tyle tytułem wstępu

Aby założyć blokadę na czas danej operacji (czyt. poleceń DELETE, INSERT, SELECT, UPDATE) potrzebujemy znać Locking Hints (po spolszczeniu HINT-y)
oraz wiedzieć do czego służą blokady tabel i poznać ich zasadę działania w Microsoft SQL Server 2000.
Najpierw przedstawię wykaz kilku HINT-ów:
- HOLDLOCK - Trzyma blokadę do końca transakcji (czyt. do końca wykonania tranzakcji, ew. do końca wsadzania danych do tabeli), wg mnie najlepiej używać jeśli nie chemy aby przy odczycie danych z tabeli ktoś inny jej nie zmodyfikował. Jest równoważna z SERIALIZABLE.
- READCOMMITED - Standardowa blokada do odczytu, kończy się w momencie zakończenia odczytywania z danej tabeli danych.
- TABLOCK - Wymusza objęcie blokadą całej tabeli.
Jeżeli chcemy założyć blokadę niestandardową na jakaś tabele, której pobieramy dane poleceniem SELECT to kod wyglądałby tak:
<?php //connect do serwera SQL $query = \"BEGIN TRAN; SELECT * FROM jakas_tabela [ WITH ( < table_hint > [ ,...n ] ) ]; COMMIT TRAN;\"; ?>
Objaśnienie: BEGIN TRAN i COMMIT TRAN zapobiegają dopisaniu jakiejkolwiek wartości do każdej tabeli w bazie. Jeżeli chcielibyśmy zablokować tabele, tak aby żadne dane nie zostały dodane w czasie pobierania przez nas danych z jakiejś tabeli, na czas wykonywania kilku (ew. większej liczby) zapytań, to przed pierwszym zapytaniem musimy wstawić BEGIN TRAN, a po ostatnim COMMIT TRAN, by zwolnić blokadę na bazie.
Żeby blokada na tabelę zadziałała trzeba zdefiniować HINT-y, parametr WITH można pominąć, ale wtedy trzeba i tak umieścić listę HINT-ów w nawiasie okrągłym (z przecinkami), zaraz za nazwą tabeli, co z resztą ma miejsce również jak używamy WITH (wtedy jest to badziej czytelniejsze zapytanie, dla kogoś kto widzi takie pierwszy raz) też trzeba listę HINT-ów umieścić w nawiasie okrągłym (z przecinkami).
Przykład:
Mamy tabele:
lockme
id INT PRIMARY KEY; opisVARCCHAR(50);
W niej jeden wiersz id=1, opis=ktoś_go_dodał.
Napiszmy skrypt, który będzie pobierał ten wieersz i przy okazji zapobiegał zmodyfikowaniu go:
<?php //connect do serwera SQL $query = \"BEGIN TRAN; SELECT * FROM lockme WITH (HOLDLOCK, TABLOCK); COMMIT TRAN\"; ?>
Wykaz umieszczania HINT-ów w zapytaniach INSERT, UPDATE oraz DELETE.
- Dla polecenia INSERT:
INSERT INTO nazwa_tabeli WITH ( < table_hint_limited > [ ...n ] ) (lista_pól) VALUES (wartości_pól);
Obowiązują tutaj wszystkie HINT-y za wyjątkiem: READPAST, NOLOCK oraz READUNCOMMITTED. - Dla polecenia UPDATE:
UPDATE nazwa_tabeli WITH ( < table_hint_limited > [ ...n ] ) SET nazwa_kolumny1='wartość1', nazwa_kolumny2='wartość2';
Obowiązują tutaj wszystkie HINT-y za wyjątkiem: READPAST, NOLOCK oraz READUNCOMMITTED. - Dla polecenia DELETE:
DELETE FROM nazwa_tabeli WITH ( < table_hint_limited > [ ...n ] ) WHERE warunki;
Obowiązują tutaj wszystkie HINT-y za wyjątkiem: READPAST, NOLOCK oraz READUNCOMMITTED.
Wszystkie HINT-y:
- FASTFIRSTROW
- HOLDLOCK
- NOLOCK
- PAGLOCK
- READCOMMITTED
- READPAST
- READUNCOMMITTED
- REPEATABLEREAD
- ROWLOCK
- SERIALIZABLE
- TABLOCK
- TABLOCKX
- UPDLOCK
- FASTFIRSTROW
- HOLDLOCK
- PAGLOCK
- READCOMMITTED
- REPEATABLEREAD
- ROWLOCK
- SERIALIZABLE
- TABLOCK
- TABLOCKX
- UPDLOCK