我使用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