【发布时间】:2010-05-12 16:02:17
【问题描述】:
我有一个存储过程,它将来自某个查询的数百万行批量插入到 SQL 数据库中。它有一个参数选择批次;当省略此参数时,它将收集批次列表并递归调用自身,以便对批次进行迭代。在(伪)代码中,它看起来像这样:
CREATE PROCEDURE spProcedure AS BEGIN
IF @code = 0 BEGIN
...
WHILE @@Fetch_Status=0 BEGIN
EXEC spProcedure @code
FETCH NEXT ... INTO @code
END
END
ELSE BEGIN
-- Disable indexes
...
INSERT INTO table
SELECT (...)
-- Enable indexes
...
现在,无论出于何种原因,这个过程可能会很慢:它无法获得锁,它使用的索引之一被错误定义或禁用。在这种情况下,我希望能够终止该过程,截断并重新创建结果表,然后重试。但是,当我尝试终止该过程时,该过程经常渗入 KILLED/ROLLBACK 状态,似乎无法返回。从谷歌我学会了做一个sp_lock,找到spid,然后用KILL <spid>杀死它。但是当我试图杀死它时,它会告诉我
SPID 75:事务回滚 进步。估计回滚 完成度:0%。预计的时间 剩余时间:554 秒。
我确实找到了一个forum message 暗示应该在另一个 spid 可以开始回滚之前杀死另一个 spid。但这对我也不起作用,而且我不明白,为什么会这样......可能是因为我递归地调用我自己的存储过程吗? (但它应该有相同的 spid,对吧?)
无论如何,我的进程只是坐在那里,死了,没有响应杀戮,并锁定了桌子。这非常令人沮丧,因为我想继续开发我的查询,而不是在我的服务器上等待几个小时而假装完成一个假定的回滚。
有什么方法可以告诉服务器不要为我的查询存储任何回滚信息?或者不允许任何其他查询干扰回滚,这样就不会花费这么长时间?或者如何以更好的方式重写我的查询,或者如何在不重新启动服务器的情况下成功终止进程?
【问题讨论】:
标签: sql-server sql-server-2008 stored-procedures locking