在页面上尝试 IX 锁定时出现 SQL 死锁
Posted
技术标签:
【中文标题】在页面上尝试 IX 锁定时出现 SQL 死锁【英文标题】:SQL deadlock while attempting IX lock on page 【发布时间】:2015-03-03 13:33:31 【问题描述】:我不明白为什么会发生这种死锁。 右边的事务只影响(更新)一行,看起来像这样:
update table1
set column1 = 'value1'
where key1 = 1
我假设 IX 请求是针对行(正在更新)所在的页面,对吧?但那不可能,因为这个页面上有一个共享锁。或者是其他页面的 IX 请求?
还有可能防止 IX 锁定(也许是一些提示)?因为我知道我只更新了一行,并且没有打算更新此事务中的任何其他内容。
更新:
Table1 - 由五列(重命名)和一个主键组成:
CREATE TABLE [dbo].[Table1](
[Key1] [int] IDENTITY(1,1) NOT NULL,
[Column1] [nvarchar](50) NOT NULL,
[Column2] [int] NOT NULL,
[Column3] [nvarchar](50) NULL,
[Column4] [int] NOT NULL,
constraint PK_Key1 primary key([Key1])
)
另一个事务由一个单独的 select 语句组成,其中包含许多连接表,包括 Table1 - 出于安全原因,我不能在这里透露。
【问题讨论】:
表(包括索引)的 DDL 和选择查询会很有帮助。 other 事务有什么作用? 出于安全原因,我无法回答您的问题——也许您至少可以尝试将其他查询提炼成与column1
和key1
完全相同的查询?您的UPDATE
可能不是问题——即使它锁定了正确的行而不是其他任何东西,如果其他查询需要触及所有内容,那仍然无济于事。您不能(通常)仅通过查看相关方来诊断死锁。
我们在这里谈论多少锁争用?您能否将此更新查询上的deadlock priority 设置为低以使其始终成为受害者,并在发生死锁时简单地重新运行它?你的其他进程可以使用 HOLDLOCK 或 SERIALIZABLE 吗?
【参考方案1】:
有一个 ROWLOCK 提示。例如:
update table1 with (ROWLOCK)
set column1 = 'value1'
where key1 = 1
【讨论】:
我试过 - with(rowlock) 导致 MS Sql 也将意图锁 (IX) 放在页面上......我正在寻找防止 IX 的方法,作为可能的解决方案死锁问题。 看起来它忽略了提示。如果您想完全避免锁定,将事务隔离级别设置为快照可能会起作用:SET TRANSACTION ISOLATION LEVEL SNAPSHOT以上是关于在页面上尝试 IX 锁定时出现 SQL 死锁的主要内容,如果未能解决你的问题,请参考以下文章
SQLException : 处理 2 个不同的表时出现死锁错误
MS-SQL 2012 中的 C# Dapper 加载程序在插入时出现死锁