Maneira correta de tirar um bloqueio exclusivo
Estou escrevendo um procedimento que irá reconciliar transações financeiras em um banco de dados ativo. O trabalho que estou fazendo não pode ser feito como uma operação de conjunto, então estou usando dois cursores aninhados.
Preciso ter um bloqueio exclusivo na tabela de transações enquanto estou reconciliando por cliente, mas gostaria de liberar o bloqueio e permitir que outras pessoas executem suas consultas entre cada cliente que processo.
Eu adoraria fazer um bloqueio exclusivo em um nível de linha em vez de um nível de tabela, maso que eu li até agora diz que não posso fazerwith (XLOCK, ROWLOCK, HOLDLOCK)
se as outras transações estiverem em execução noREADCOMMITED
nível de isolamento (que é para mim).
Eu estou tendo um bloqueio exclusivo de nível de tabela corretamente, e há alguma maneira no Server 2008 R2 para fazer bloqueios exclusivos de nível de linha funcionar da maneira que eu quero sem modificar as outras consultas em execução no banco de dados?
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