我正在編寫一個過程,將協調實時數據庫上的finical交易。我正在做的工作不能作爲集合操作完成,所以我使用了兩個嵌套遊標。正確的方式採取獨佔鎖
我需要一個排它鎖的事務表,而我每個客戶端的協調,但我想解除鎖定,並讓其他人在每一個客戶我處理之間運行他們的查詢。
我很想做一個行級別而不是表級別一排它鎖,但what I have read so far說,如果其他事務在READCOMMITED
隔離級別(這是對我來說)運行,我不能做with (XLOCK, ROWLOCK, HOLDLOCK)
。
我是否正確地採取了表級排它鎖,並且有在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
我想弄明白爲什麼你需要獨佔鎖。其他人可能會插入記錄嗎?其他人更新記錄?你擔心其他人對數據有不一致的看法嗎? – Laurence
@Laurence我很擔心其他人會看到不一致的狀態。我試圖糾正一個錯誤,影響了一小部分的客戶端,但是這個糾正過程在幾個表中留下了幾個相互依賴的行(我實際上會鎖定5個表,但我的代碼示例簡化爲一個表)處於不一致狀態校正過程。每個客戶端的不一致性是孤立的,但是在這個客戶端上執行'SELECT SUM(ColA)FROM trnHistory'會在「更正」過程中返回一個不正確的值。所以我需要採取排他鎖來防止讀取。 –
我不明白爲什麼交易不能保護你免受這種情況的影響,除非你有人在做read_uncommitted。 – Laurence