【问题标题】:SQL Server 2008 - INSERT for table working but UPDATE/DELETE hangsSQL Server 2008 - 插入表工作,但更新/删除挂起
【发布时间】: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 未触发,该命令仍在执行),似乎事情被卡住了:

图像中的表名被遮盖了——但这是我在其中执行INSERTUPDATE 的目标表。

有什么想法吗?

【问题讨论】:

  • 该问题没有足够的信息来回答它。我不关闭它的原因是您提供了很多总体上很好的信息。您似乎遇到了阻塞问题。在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


【解决方案1】:

请在删除前与其他表检查外键 您可以使用删除级联选项更改外键约束,如下所示。这将在删除时删除与主表行相关的 chind 表行。

ALTER TABLE MainTable
ADD CONSTRAINT fk_xyz  
FOREIGN KEY (xyz)  
REFERENCES ChildTable (xyz) ON DELETE CASCADE 

【讨论】:

  • 如果 FK 阻止删除,他将收到错误消息。无论如何,基于猜测的答案没有那么有用。
  • @Morteza 该表没有外键。
  • @thedude 您可以重新创建表,然后检查您的日志。
  • @Morteza 我应该寻找什么?问题是这个问题几乎不会发生。这是一个 24/7 全天候在许多站点上活动的系统,但仅偶尔发生一次。我将无法重新创建它。
  • @Morteza UPDATE 非常简单。我现在手边没有它,但它基本上是:IF (1=0) BEGIN UPDATE TheTable SET TheValue=@val WHERE TheDate=@date END IF 故意为假 - 只是为了证明即使UPDATE 从未触发也会出现此问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 2011-05-15
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多