通过多任务更新SQL Server 2008表时出现死锁

时间:2019-02-01 10:06:43

标签: sql sql-server sql-server-2008

我在SQL Server中有一个具有以下架构的表:

RunJob Table 
(
    id identity,
    SqlCode nvarchar(max)   -- store dynamic sql which will be executed by SP.
    Start_time              -- will be null at the start,  will be updated at the start of SqlCode column's dynamic sql execution
    EndTime                 -- end time of SqlCode dynamic sql execution 
    Status char(2)          -- initially it will be NS(no started), IP (in progress while execution of SqlCode) , CO or FA ( completed or failed at the end)
)

表大约有25000行。我正在使用C#多任务程序从4个线程调用一个SQL Server存储过程。

因此,同一存储过程将被同时调用4次。此存储过程有一个while循环,并在Startime为null且状态为NS(未启动)时获取最大ID。

对于该行,存储过程将开始日期设置为IP,从SqlCode列中获取文本并执行,最后,它将更新Endtime和{{1 }}到status

在存储过程中,在读取数据时,我不使用锁,而在更新时,我使用行锁。

但是在更新Co\FA表时,我仍然遇到僵局。

有人可以建议我做些什么来避免死锁吗?

还有一点-使用未提交的事务级别读取后,我得到的死锁更少。 ^

2 个答案:

答案 0 :(得分:0)

根据我的经验,在处理并发方案时,您描述的是最好在非常细粒度的级别上使用 sp_getapplock (紧随其后的是sp_releaseapplock)。 安迪·诺维克(Andy Novick)在本文中对此做了很好的解释: https://www.mssqltips.com/sqlservertip/3202/prevent-multiple-users-from-running-the-same-sql-server-stored-procedure-at-the-same-time/

答案 1 :(得分:0)

如果您打算将工作负载平均分配到这四个线程。然后,您可以考虑使用NTILE(4)over(cols)来获取thread_numbers。

因此,如果这会导致死锁,则可以避免执行MAX(id)逻辑的WHILE循环。

最好了解一下存储过程中正在发生的事情,以提出其他替代方案