【发布时间】:2018-12-10 12:55:04
【问题描述】:
我们目前正在我们的开发环境 (sql server 2016) 中测试从 100 提高到 130 的兼容性级别 (cl)。切换后我们注意到一些错误:
could not execute batch command.[SQL: SQL not available] Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
经过一些研究、跟踪和调试,我能够确认我们确实遇到了死锁问题。 我们使用 .net 应用程序,它使用 nhibernate 访问数据库。一些内部任务(在 .net 应用程序中)可以为我们设置并行性以更快地完成。 这些任务通常以不可能出现(行)死锁的方式分配它们的工作量。 IE。任务 1 和任务 2 可以大致同时访问表 A 和表 B,但它们永远不会访问每个表中的相同行。
任务调用一些存储过程,这些过程执行一些简单的操作,例如:
UPDATE dbo.Tab1
SET dbo.Tab1.Col1 = 'ValueY'
FROM dbo.Tab2
JOIN dbo.Tab3
JOIN dbo.Tab4
…
WHERE Tab1.Col.2 = 'ValueX'
本质上这将通过 Tab1 运行,搜索要更新的行并更新那些。
这一切在兼容级别 (cl) 100 中运行良好。 切换到 cl 130 后有时会出现死锁,以前没有遇到过。
死锁图显示了同一对象 id/hobt id 上的两个 Key 锁,其中两个不同的服务器进程持有 X-Lock 并请求 U。
如果我在表 Tab1 中添加不相关的行,对于这个特定的测试,它会将页数增加到 23,并且没有更多问题。
我已阅读,这整个问题可能是由少量的行/页引起的。与具有数百万行的表相比,优化器/服务器的行为不同,这会导致不同的锁定行为并可能导致死锁。
但这并没有回答我的问题:兼容性级别从100切换到130时是否会直接影响锁定,甚至可能导致死锁问题,这是以前没有的?
PS:这不是锁升级问题,因为我已经为 Table Tab1 关闭了它。
【问题讨论】:
标签: sql-server deadlock sql-server-2016 compatibility-level