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

c# dapper deadlock sql sql-server

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

在加载器的顶部,我发出'SET RECOVERY SIMPLE'(这样做是为了尝试解决这个问题)。

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

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

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

我不知道如何调试这个。在我的'catch'语句中,我发出这个SQL命令来捕获正在运行的其他内容,但是每次出现错误时它都显示NOTHING正在运行。因此,如果没有运行,为什么我一直在插入死锁?

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()

热门答案

在我的'catch'语句中,我发出此SQL命令来捕获正在运行的其他内容

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

你要做的事情从根本上说是错误的。更不用说,您已经有了捕获死锁信息的方法:

并且,作为最后一个问题: sys.dm_exec_sessions权限

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



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因