2011-01-04 5 views

Odpowiedz

11
BEGIN TRAN 

    SELECT 1 
    FROM Table 
    WITH (XLOCK, ROWLOCK) 

COMMIT TRAN 

To wystarczy.

EDIT

Jak wspomniano przez innych, nie można zablokować wiersz nie należy czytać. Jedynym sposobem, wiem, robi to w sposób następujący:

WITH (UPDLOCK, TABLOCK) 

I to przy założeniu, że WITH (NOLOCK) nigdy nie jest używany w SELECT (których należy unikać w każdym razie).

Testowałem to i będzie działać, chociaż TABLOCK powinien być używany tylko w skrajnych przypadkach. Z pewnością, jeśli wymagana jest współbieżność, jest to złe rozwiązanie i potrzebna byłaby inna forma blokowania. Jednym ze sposobów jest aktualizacja kolumny bitowej "Dostępne True/Fałsz" i tylko odczytanie wierszy, w których Dostępne = Prawda. Zgodnie z sugestią @ gbn, READPAST może być użyty z tym.

+1

Właśnie to przetestowałem i XLOCK działa tak dobrze jak UPDLOCK dla wybranych. Zobacz także: http://sqlblog.com/blogs/louis_davidson/archive/2006/12/13/does-xlock-always-prevent-reads-by-others.aspx –

+0

Tak, masz rację. Jednak słusznie lub niesłusznie uważam, że PO szuka wyłącznej blokady, ponieważ powiedział, że chce "zapobiec CRUD". Nie wiem, czy jest to tylko przeciwko aktualizacjom, czy zawiera blokowanie wierszy, które zostały przeczytane. Dlatego wybrałem wyłączną blokadę. Jeśli nie jest to przeciwko odczytanym wierszom, to w 100% użyłbym UPDLOCK. – IamIC

+0

+1 @KM dzięki za link. Ciekawy! – IamIC

5

spróbuj użyć ROWLOCK i UPDLOCK transakcji wewnątrz coś takiego:

BEGIN TRANSACTION 

SELECT @ID = ID 
FROM YourTable WITH (ROWLOCK, UPDLOCK) 
WHERE .... 

--more-- 

COMMIT TRANSACTION 

jednak nie można zapobiec SELECT, który używa wskazówkę NOLOCK z „brudne” czytając to.

+0

UPDLOCK nie uniemożliwi odczytów. – IamIC

+0

@ IanC, tytuł pytania: ** Jak zablokować wyłącznie wiersz, który uniemożliwia działanie CRUD ** –

+0

@KM Wiem. "Jak * blokować wyłącznie *" = XLOCK. :-) – IamIC

1

Serwer SQL już natywnie blokuje rekord z brudnych odczytów podczas aktualizacji. Powoduje to zablokowanie wywołania select, dopóki nie zakończy się połączenie update/insert.

+0

Mimo że wyrażenie jest prawdziwe, użycie SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED (lub określenie NOLOCK) nadal będzie zwracać brudne odczyty. –

0

Możliwe jest blokowanie wiersza za pomocą wskazówki blokowania WITH (ROWLOCK), jednak instrukcja SELECT może zawsze ominąć ją, dodając wskazówkę blokującą WITH (NOLOCK), która zapewni brudny odczyt.

+0

To nie jest prawda. Z XLOCK, ROWLOCK zagwarantuje blokadę odczytu w rzędzie. W trakcie zainteresowania NOLOCK jest przestarzały. – IamIC

+0

Właściwie to prawda. Mój przykład używa ROWLOCK, a nie XLOCK. Jednak prosty test udowodni, że NOLOCK będzie nadal zwracał wiersze w stosunku do tabeli z wyłączną blokadą. rozpocząć tran select * from tabela z (xlock, dulka) gdzie primarykeyid = 1 pomocą innego połączenia: select * from tabela z (NOLOCK) gdzie primarykeyid = 1 Drugi SELECT nadal zwraca wiersze, chociaż wyłączna blokada istnieje w wybranym wierszu. –

+0

+1, to zadziała tak dobrze, jak odpowiedź @ IanC –

1

Jak również dulka, XLOCK sugerowane przez innych folk, uważam READPAST oprócz

pozwala Pozwala innych czytelników i pisarzy do pominąć blokadę na tym wierszu. Może to zwiększyć współbieżność, ponieważ blokada ustawiona przez ROWLOCK, blokowanie XLOCK s w przeciwnym razie

+1

Dobra uwaga, chociaż PO powinien pamiętać, że to pominięcie oznacza całkowite pominięcie zamkniętych wierszy, ponieważ nie pojawią się one w wynikach, co może, ale nie musi być pożądane. – IamIC

+0

Bardzo podoba mi się pomysł READPAST, ponieważ pozwoli to deweloperowi na obsłużenie możliwości nie odnalezienia wiersza, a zatem kontynuowanie go bez wystąpienia impasu. – Gwasshoppa

Powiązane problemy