在页面上尝试 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 事务有什么作用? 出于安全原因,我无法回答您的问题——也许您至少可以尝试将其他查询提炼成与column1key1 完全相同的查询?您的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 加载程序在插入时出现死锁

“源映射错误:TypeError:尝试获取资源时出现 NetworkError。”在本地页面上

如何在我的项目上设置惯性,当我尝试加载登录页面时出现错误

尝试访问部署在 Netlify 上的站点时出现“找不到页面”