我有一个连接到 SQL Server 2014 数据库的应用程序,该数据库将多行合并为一行。当应用程序运行时,没有与此数据库的其他连接。
首先,选择特定时间跨度内的一组行。此查询使用与聚集查找合并的非聚集查找(TIME 列)。
select ...
from FOO
where TIME >= @from and TIME < @to and ...
然后,我们在 C# 中处理这些行,并将更改写入单个更新和多个删除,每个块会发生多次。这些也使用非聚集索引查找。
begin tran
update FOO set ...
where NON_CLUSTERED_ID = @id
delete FOO where NON_CLUSTERED_ID in (@id1, @id2, @id3, ...)
commit
当我使用多个并行块运行此程序时,我遇到了死锁。我尝试使用ROWLOCK
为了update
and delete
但由于某种原因,这导致了比以前更多的死锁,即使块之间没有重叠。
然后我尝试了TABLOCKX, HOLDLOCK
on the update
,但这意味着我无法执行我的select
并行,所以我失去了并行的优势。
知道如何避免死锁但仍然处理多个并行块吗?
使用起来安全吗NOLOCK
on my select
在这种情况下,假设块之间没有行重叠?然后TABLOCKX, HOLDLOCK
只会阻止update
and delete
, 正确的?
或者我应该接受死锁的发生并在我的应用程序中重试查询?
UPDATE(附加信息):到目前为止,所有死锁都发生在update
and delete
阶段,没有一个select
。如果我今天无法解决这个问题(之前未启用正确的跟踪标志),我将尝试获取一些死锁日志。
UPDATE:这是发生死锁的两种安排ROWLOCK
,它们都仅指delete
语句及其使用的非聚集索引。我不确定这些是否与没有任何表提示时发生的死锁相同,因为我无法重现其中任何一个。
![Deadlock 2](https://i.stack.imgur.com/Q3hWr.png)
询问 .xdl 是否还需要其他任何内容,我有点厌倦了附加整个内容。