У меня есть хранимая процедура, которая вставляет в базу данных 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, откуда, похоже, нет возврата. Из Google я научился делать sp_lock
, найти спид и затем убить его с помощью KILL <spid>
. Но когда я пытаюсь убить его, он говорит мне
SPID 75: откат транзакции в
прогресс. Расчетный откат
Завершение: 0%. Расчетное время
Осталось: 554 секунды.
Я нашел сообщение на форуме , намекающее, что другой спид должен быть убит, прежде чем другой сможет начать откат. Но это тоже не сработало для меня, плюс я не понимаю, почему это так ... может ли это быть потому, что я рекурсивно вызываю свою собственную хранимую процедуру? (Но это должен быть тот же спид, верно?)
В любом случае, мой процесс - просто сидеть там, быть мертвым, не отвечать на убийства и блокировать стол. Это очень расстраивает, так как я хочу продолжать разрабатывать свои запросы, не ждать часа на моем сервере, сидящем мертвым, притворяясь, что заканчиваю предполагаемый откат.
Есть ли способ, с помощью которого я могу сказать серверу, чтобы он не сохранял информацию об откате для моего запроса? Или не позволять другим запросам вмешиваться в откат, чтобы он не занял так много времени? Или как лучше переписать мой запрос, или как успешно завершить процесс, не перезагружая сервер?