【发布时间】:2014-06-29 01:59:25
【问题描述】:
我有一个简单的存储过程,它只对表执行INSERT。
存储过程接受几个参数(从 C# 代码调用)并执行简单的插入操作。
插入时一切正常 - 但是,在某些情况下,可能存在 PK 违规,在这种情况下,我会检查错误代码,如果存在 PK 违规 - 然后发送UPDATE。
插入UPDATE 后,存储过程就挂起。它不会抛出错误或任何东西。
我尝试将UPDATE 替换为DELETE+INSERT 只是为了看看是否有任何作用,但它没有。
最奇怪的是——代码甚至没有到达UPDATE!
我确定了 IF 语句是假的,问题仍然存在!
C# 代码大约每秒调用一次此存储过程。即使存储过程挂起很长时间,在我注释掉UPDATE 并更新存储过程使其只有INSERT 之后,所有行都会被插入。我猜它在某处缓冲它们。
我尝试将UPDATE 命令移动到不同的存储过程并从原始存储过程调用它 (EXEC updateSproc)。这似乎解决了问题
然而,乍一看,经过仔细检查,我可以看到更新仍然无法正常工作。我猜唯一发生的事情是 updateSproc 挂起而不是原来的 - 让 C# 代码继续并插入新值。
我尝试使用原始存储过程从其他表中更新和删除,没有问题。
好像这张表不允许UPDATE,DELETE。
一切都以“sa”的形式运行
表并没有那么大,大约有一百万行。
碎片没问题。页面大小的使用率约为 95%。好像没问题。
表上只有 1 个索引(PK 聚集) - 没什么特别的。
有什么想法吗?
编辑
我检查了你的建议,这就是我得到的:
exec sp_who2 返回:1529 05/12 17:39:27 .Net SqlClient Data Provider 53 0
dbcc INPUTBUFFER(53) 返回:RPC Event 0 TheDBName.dbo.AddInstrData;1
AddInstrData 是被调用的存储过程。在里面,有一个简单的INSERT,后面跟着一个UPDATE。
就像我之前写的那样,我将 UPDATE 移动到一个新的存储过程中,只有一个命令(UPDATE)。
所以现在,AddInstrData 有一个 INSERT,后跟一个 EXEC UpdateInstrData。
在将UPDATE 移动到新的存储过程之前,根本没有插入数据。
将其移动到新的存储过程后,数据被正确插入 - 我猜挂起刚刚移动到新的存储过程,因为我可以在 Activity Monitor 中看到它卡在 RUNNABLE 上并且实际上没有执行任何更新。
另外,SQL Server 版本是:Microsoft SQL Server Management Studio 10.50.1600.1
重要提示:
这个问题并不总是发生。一切都可以正常工作很长时间,然后突然就开始发生了。可能会有系统时间变化,但我认为这与它无关。
编辑 2
我尝试将 UPDATE 放回原始存储过程中,并将其放入 IF (1=0) 语句中。
这仍然挂起!就好像 UPDATE 语句的存在导致了问题 - 它位于一个从未实际执行的块中。
重要提示2:
如果我在 SMSS 中打开一个新窗口并手动执行EXEC AddInstrData,则阻塞停止,所有排队的数据(它在哪里排队?)都插入到表中。
新进展
我想我找到了罪魁祸首!
由于以下命令(即使UPDATE 未触发,该命令仍在执行),似乎事情被卡住了:
图像中的表名被遮盖了——但这是我在其中执行INSERT 和UPDATE 的目标表。
有什么想法吗?
【问题讨论】:
-
该问题没有足够的信息来回答它。我不关闭它的原因是您提供了很多总体上很好的信息。您似乎遇到了阻塞问题。在
UPDATE“挂起”时执行sp_who2。通过查看被阻止的列,您将看到哪个会话阻止了更新。另外,请发布所有相关代码。 -
你真的每秒都在调用 sp 吗?
-
+1
usr。执行sp_who2后,使用DBCC INPUTBUFFER(<BlkBy>)查看正在执行阻止会话的内容。否则,您可以安装sp_WhoIsActive(download) 存储过程(由 Adam Machanic 编写)来获取这些信息。 -
@meda 是的。该系统是基于硬件的,每秒左右收集信号
-
@usr sp_who2 数据是否显示在活动监视器中?因为在活动监视器中似乎没有任何阻塞。如果没有 - 我明天可以访问并检查您的建议和 Bogdan Sahlean 的建议
标签: c# sql sql-server stored-procedures