我想得到一个改进我的设置的建议,导致sql server返回死锁消息。我有多个线程应用程序实际上使用TaskParallel库,每个任务将使用存储过程从表中选择一个id用于其处理。我立即从同一语句中的表中删除该id,我认为这是导致死锁的原因。该表由一列没有索引的唯一ID组成。我想过定期进行批量删除,但这意味着要在多个服务器上保留已使用的ID。
这是我的sql存储过程:
CREATE PROCEDURE [dbo].[get_Ids]
@id nvarchar(20) OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Select top 1 @id = siteid from siteids
delete siteids where siteid = @id
END
有没有更好的方法呢?我的进程工作得非常快,我曾经从webrequest服务请求这个id,但这需要3秒钟。
答案 0 :(得分:1)
要尝试的一些事情: 也许尝试向数据库暗示您将删除刚刚选择的记录,这样它就会提前获取锁定。为此,您需要将整个过程包装在事务中,然后提示选择。应该看起来像:
BEGIN TRANSACTION
SELECT TOP 1 @id = siteid from siteids WITH (UPDLOCK, HOLDLOCK)
DELETE siteids WHERE siteid = @id
COMMIT TRANSACTION
还要确保siteid
列已编入索引(或将其标记为主键,因为您说它是唯一的),否则它必须扫描表以获取要删除的记录,这可能会导致死锁更糟糕的是因为它花了更多时间删除。
对于一般的死锁,运行SQL分析器并查看死锁图的样子 - 可能还有其他事情正在发生。