我有一个简单的表Item
,其中有十几列,主键是2列,ItemId nvarchar(20)
和Tag nvarchar(200)
。
我们已经将所有select语句切换为使用WITH (NOLOCK)
只是为了确保如下所示:
SELECT ItemId, Tag, Description FROM Item WITH (NOLOCK) WHERE Tag LIKE 'PART_00%'
现在我有主服务器要接收一份工作,他必须删除并重新创建他收到的每个项目。该服务器选择要执行的所有操作的列表(无重复项),然后将此列表分为多个部分,并将每个子列表发送给其他服务器。这些其他服务器做简单的事情:
现在,实际问题是由于资源的限制,我PageLock
由于SQL
正在将RowLock
升级为PageLock
而出现了死锁。我们实际上并不在乎,因此我禁用了表锁升级,并更改了删除查询以确保我们使用的是RowLock
,所以这就是查询
DELETE FROM Item WITH (ROWLOCK) WHERE Tag LIKE 'PART_0010C'
现在,即使我们已尽一切努力使用KeyLock
,我们仍在此表的主键上获得RowLock
。基于System_health:event_file
,我确实遇到了2个完全不同的pk值的冲突。这怎么可能呢 ?查询也不在事务中,以确保没有任何形式的圆形锁。
在下面,您可以清楚地看到2个完全独立的连接,即pId 109和111(仅执行上面显示的delete语句)正在创建KeyLock
,即使实际查询是针对2个不同的特定pk值。
为此,尝试了不同的查询,现在我使用LIKE
而不是使用=
进行删除。我之所以需要使用LIKE
的原因是在工作时间以外运行的其他一些流程将使用LIKE
删除,因为许多记录需要删除,并且它们以特定的Tag
开头,所以批量删除要快得多。无论如何,使用=
都无法解决问题。我还有很多KeyLock
。