Правильный способ взять эксклюзивный замок

Я пишу процедуру, которая будет согласовывать конечные транзакции в действующей базе данных. Работу, которую я выполняю, нельзя выполнить как заданную операцию, поэтому я использую два вложенных курсора.

Мне нужно сделать эксклюзивную блокировку таблицы транзакций, пока я выполняю согласование для каждого клиента, но я бы хотел снять блокировку и позволить другим людям выполнять свои запросы между каждым клиентом, который я обрабатываю.

Я хотел бы сделать эксклюзивную блокировку на уровне строк вместо уровня таблицы, ночто я прочитал до сих пор говорит, что я не могу сделатьwith (XLOCK, ROWLOCK, HOLDLOCK) если другие транзакции выполняются вREADCOMMITED уровень изоляции (что для меня).

Правильно ли я использую эксклюзивную блокировку на уровне таблицы, и есть ли в Server 2008 R2 способ сделать так, чтобы монопольные блокировки на уровне строк работали так, как я хочу, без изменения других запросов, выполняемых в базе данных?

declare client_cursor cursor local forward_only for 
     select distinct CLIENT_GUID from trnHistory
open client_cursor

declare @ClientGuid uniqueidentifier
declare @TransGuid uniqueidentifier

fetch next from client_cursor into @ClientGuid
WHILE (@@FETCH_STATUS <> -1)
BEGIN
    IF (@@FETCH_STATUS <> -2)
    BEGIN
        begin tran

        declare @temp int

        --The following row will not work if the other connections are running READCOMMITED isolation level
        --select @temp = 1 
    --from trnHistory with (XLOCK, ROWLOCK, HOLDLOCK) 
    --left join trnCB with (XLOCK, ROWLOCK, HOLDLOCK) on trnHistory.TRANS_GUID = trnCB.TRANS_GUID
    --left join trnClients with (XLOCK, ROWLOCK, HOLDLOCK) on trnHistory.TRANS_GUID = trnClients.TRANS_GUID
    --(Snip) --Other tables that will be "touched" during the reconcile
    --where trnHistory.CLIENT_GUID = @ClientGuid

        --Works allways but locks whole table.
    select top 1 @temp = 1 from trnHistory with (XLOCK, TABLOCK) 
    select top 1 @temp = 1 from trnCB with (XLOCK, TABLOCK)
    select top 1 @temp = 1 from trnClients with (XLOCK, TABLOCK)
    --(Snip) --Other tables that will be "touched" during the reconcile

        declare trans_cursor cursor local forward_only for 
                select TRANS_GUID from trnHistory where CLIENT_GUID = @ClientGuid order by TRANS_NUMBER
        open trans_cursor

        fetch next from trans_cursor into @TransGuid
        WHILE (@@FETCH_STATUS <> -1)
        BEGIN
            IF (@@FETCH_STATUS <> -2)
            BEGIN

                --Do Work here

            END
            fetch next from trans_cursor into @TransGuid
        END

        close trans_cursor
        deallocate trans_cursor

            --commit the transaction and release the lock, this allows other 
            -- connections to get a few queries in while it is safe to read.
        commit tran
    END

    fetch next from client_cursor into @ClientGuid
END 

close client_cursor
deallocate client_cursor

Ответы на вопрос(2)

Ваш ответ на вопрос