【发布时间】:2021-06-15 11:44:23
【问题描述】:
stackoverflow 上已经有这个问题的不同版本,但没有一个版本能帮助我找到问题的根源。所以,我在这里再次详细说明我的问题。
我们随机收到 Transaction (Process ID xx) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 。让我明确一点,这不是行或表级锁定。我已经尝试了足够多的猜测/随机事物;我需要关于如何解决通信缓冲区死锁的详细分步指南。
如果您对具体细节感兴趣,请继续阅读。
场景的具体细节:我们有一个非常简单的基于 Dapper ORM 的 C# .net 核心 Web API,它接收请求并对托管在此 Microsoft Sql 服务器上的数据库执行 CRUD 操作。为此,连接管理器(注册为范围服务)在请求范围内打开一个新的IDbConnection 连接;此连接用于执行删除、插入、更新或获取。对于插入/更新/删除 C# 行看起来像这样 await connection.ExecuteAsync("<Create update or delete statement>", entity); 对于 GET 请求,我们只需运行 await connection.QueryFirstOrDefaultAsync<TEntity>("<select statement>", entity); ;有 5 种类型的实体(都呈现简单的非关系表)。他们都按 ID CRUD。
到目前为止已经尝试过什么
- MAXDOP=1 SQL 语句的查询提示
- 确保一种实体在给定时间点只有 1 个实体 CRUD。
- 正在重新启动 SQL 服务器/应用程序实例
- 确保端口/RAM/CPU/网络带宽没有耗尽
- 改变 DATABASE XXXXXX SET READ_COMMITTED_SNAPSHOT ON/OFF
- 尽可能减少事务
- 持久重试策略作为一种解决方法(以处理问题的随机瞬态性质)
- 每个实体类型一个线程
服务器规格: 我们在具有 64 个内核和 400GB RAM 的虚拟机中托管了 Microsoft Sql Server 2016 On Azure。此服务器上的通常工作负载是 10% CPU 和 30% RAM,偶尔会上升到 80% CPU 和 350GB RAM。在此问题发生的所有时间,CPU 使用率都低于 20%(大多数情况下在 10% 左右,只有一次是 20%,RAM 在所有情况下都低于 30%)。
根据@Dan Guzman 的请求的死锁 XML 事件
这个帖子的文件太大,所以创建了这个谷歌驱动器文件。请点击以下链接,然后在右上角点击下载。它是一个 zip 文件。
https://drive.google.com/file/d/1oZ4dT8Yrd2uW2oBqBy9XK_laq7ftGzFJ/view?usp=sharing
【问题讨论】:
-
将死锁 xml 添加到您的问题中。有关从 system_health xe 跟踪中提取事件的示例,请参阅 this answer。
-
@DanGuzman 由于文件大小限制,我不得不将文件放在谷歌驱动器上。我在上面的帖子中添加了文件链接。请点击右上角的下载按钮。谢谢。
-
我看到所有参数都声明为
nvarchar(4000)。当引用的列类型不同时,这可能会阻止索引的有效使用,从而导致在UPDATE查询期间进行完全扫描,从而导致死锁。尝试使用与引用列类型相同的强类型参数,并检查执行计划的效率。 -
@DanGuzman,非常感谢。杰出的。它似乎是固定的。即使处理了 200 万个请求,也不例外。 Dapper 默认参数大小 4000 不适合我的情况。
标签: c# sql-server deadlock sqlexception database-deadlocks