我们最近将一些代码从 C# 移至 SQL (SQL Server 2005) 以尝试防止并发问题。然而,在 SQL 中,我们现在遇到了死锁。我无法重新创建获得死锁的步骤,但是我能够在 SQL 跟踪中捕获它。
表上没有触发器,但有几个索引支持搜索。
根据跟踪,死锁是由两个人在同一条记录上运行相同的更新语句引起的:
UPDATE myTable
SET
col2 = @var2 + col2
,col3 = CASE WHEN (@Var2 <= 0 OR @Var2 + Col2 <= 0)
THEN Col3
ELSE
CONVERT
(
dbo.MoneyInfo,
@var3 + ':' + @Var4 + ':' + @Var5
)
END
OUTPUT INSERTED.Col0,
Inserted.Col2,
Inserted.Col3
WHERE Col0 = @Var1
dbo.MoneyInfo
是自定义 CLR 类型。该表看起来像:
create table myTable
(
col0 int,
col1 int,
col2 decimal(18,2),
col3 dbo.MoneyInfo
)
col0 是非聚集主键(PK_Stock),col1 是聚集索引(IX_Item)
这是跟踪中的死锁图:
我不明白运行完全相同的存储 proc 语句的 2 个人如何最终会在同一个语句上陷入死锁。第一个连接不应该锁定记录,迫使第二个连接等待它可用吗?对于造成这种僵局的原因,我还有什么可以调查的吗?可能是因为 OUTPUT 语句吗?