我在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
表时,我仍然遇到僵局。
有人可以建议我做些什么来避免死锁吗?
还有一点-使用未提交的事务级别读取后,我得到的死锁更少。 ^
答案 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循环。
最好了解一下存储过程中正在发生的事情,以提出其他替代方案