我使用SQL Server 2012的我有一個可重複讀事務,我執行此查詢:稍後使用INSERT將SELECT COUNT(SomeId)與SomeId相同:適當的鎖定策略?
select count(SomeId)
from dbo.MyTable
where SomeId = @SomeId
SomeId
是它的值可重複表(認爲外鍵)列。但是,SomeId
不是任何索引的成員,也不是外鍵。
在交易之後,我將記錄插入dbo.MyTable
具有相同@SomeId
,從而改變什麼select count(*)
將返回被我再次運行它:
insert into dbo.MyTable (SomeId, ...)
values (@SomeId, ...)
在我的應用程序可以執行該交易的多個線程與此同時。正因爲如此,我在insert
聲明中出現了死鎖。起初,我認爲updlock
將適用於select
聲明,但我很快意識到它不會工作,因爲我實際上沒有更新由select count(SomeId)
選擇的行。
我的問題是:有沒有辦法避免潛在的昂貴的表鎖?有沒有辦法鎖定涉及SomeId
的行,即使它們還沒有被插入(奇怪,我知道)?我想強制其他線程等待原始事務完成其工作,但我不想不必要地鎖定行。
編輯
這裏就是我試圖完成:
我只想插入多達八行特定SomeId
。有幾個不相關的進程可能會同時啓動這些事務之一。 select count
檢測是否已有八行,並導致該操作在該過程中失敗。如果計數小於8,那麼同一個事務將執行額外的工作,然後在最後插入一條記錄,因此select count
重新運行時會有效增加計數。我在insert
聲明中遇到了僵局。
你的描述讓我懷疑你可能正在接近這個錯誤的方式。你能解釋一下你試圖解決的實際問題嗎? –
當然,我會添加更多的上下文。 – NathanAldenSr
我在想'也許在'SomeId'上創建一個索引將是一個不錯的選擇,然後以某種方式鎖定特定'SomeId'的索引。我不熟悉鎖定在這個層面上,所以我只是直覺。 :) – NathanAldenSr