MS-SQL 2012 中的 C# Dapper 加载程序在插入时出现死锁

Posted

技术标签:

【中文标题】MS-SQL 2012 中的 C# Dapper 加载程序在插入时出现死锁【英文标题】:C# Dapper loader in MS-SQL 2012 deadlocks on insert 【发布时间】:2016-07-28 14:20:43 【问题描述】:

运行 Microsoft SQL 2012 标准,无压缩,无分区。 在 Windows Server 2008 R2 上运行。 我的加载程序是 VS C# 2013,纯 64 位,.NET 4.5.2 我为我的 ORM 使用 Dapper 1.42。 我不使用提交/回滚/事务逻辑,这些只是简单的插入。

在加载程序的顶部,我发出“SET RECOVERY SIMPLE”(这样做是为了尝试解决此问题)。

加载程序读取 .csv,对数据进行一些处理,然后进行插入,这实际上是最简单的程序形式,只有几行代码。加载程序从不进行选择。加载程序是此服务器(测试服务器)上运行的唯一进程。加载器不是多线程的。我在插入时执行 commandtimeout = 0。

我不断收到“事务(进程 ID xx)在锁定资源上与另一个进程死锁,并已被选为死锁受害者。重新运行事务'。

这个错误听起来很明显,它说我有 2 个进程正在运行,其中一个正在死锁。但是我在测试服务器上,我是唯一的用户,没有其他进程在运行。

我不知道如何调试它。在我的“catch”语句中,我发出这个 SQL 命令来捕捉正在运行的其他内容,但每次我收到错误时它都显示没有运行。那么,如果什么都没有运行,为什么我总是在插入时遇到死锁?

SELECT L.request_session_id AS SPID, DB_NAME(L.resource_database_id) AS DatabaseName, O.Name AS LockedObjectName, P.object_id AS LockedObjectId, L.resource_type AS LockedResource, L.request_mode AS LockType, ST.text AS SqlStatementText, ES.login_name AS LoginName, ES.host_name AS HostName, TST.is_user_transaction as IsUserTransaction, AT.name as TransactionName, CN.auth_scheme as AuthenticationMethod
FROM sys.dm_tran_locks L
LEFT JOIN sys.partitions P ON P.hobt_id = L.resource_associated_entity_id
LEFT JOIN sys.objects O ON O.object_id = P.object_id
LEFT JOIN sys.dm_exec_sessions ES ON ES.session_id = L.request_session_id
LEFT JOIN sys.dm_tran_session_transactions TST ON ES.session_id = TST.session_id
LEFT JOIN sys.dm_tran_active_transactions AT ON TST.transaction_id = AT.transaction_id
LEFT JOIN sys.dm_exec_connections CN ON CN.session_id = ES.session_id
CROSS APPLY sys.dm_exec_sql_text(CN.most_recent_sql_handle) AS ST
WHERE DB_NAME(L.resource_database_id) = DB_NAME()

【问题讨论】:

【参考方案1】:

在我的“catch”语句中,我发出这个 SQL 命令来捕捉正在运行的其他内容

当发生死锁时,受害者事务将回滚。这会释放所有锁,从而允许竞争事务继续进行。只有在回滚完成后,控制权才会返回给受害者会话,并引发异常。当您的catch 运行时,并发进程可能已经完成。

您尝试做的事情根本不正确。更不用说,您已经拥有方法来捕获死锁信息:

Save Deadlock Graphs (SQL Server Profiler) Analyze Deadlocks with SQL Server Profiler How to use Extended Events to proactively monitor your SQL Server for Deadlock issues Capturing Deadlocks in SQL Server

最后一期:sys.dm_exec_sessions permissions:

如果用户在服务器上拥有 VIEW SERVER STATE 权限,用户将看到 SQL Server 实例上所有正在执行的会话;否则,用户将只能看到当前会话

【讨论】:

以上是关于MS-SQL 2012 中的 C# Dapper 加载程序在插入时出现死锁的主要内容,如果未能解决你的问题,请参考以下文章

C# Dapper基本用法

使用没有字母参数的 Postgresql 的 Dapper 存储过程

将 Dapper 与 SQL Server 一起使用

使用 Dapper (C#) 调用 PostgreSQL 存储过程

如何使用 Dapper.NET 将 C# 列表插入数据库

没有自定义 SQL 的 Dapper 中的多重映射