Ошибка транзакции SQL: текущая транзакция не может быть зафиксирована и не может поддерживать операции записи в файл журнала
У меня похожая проблема сТекущая транзакция не может быть зафиксирована и не может поддерживать операции записи в файл журнала., но у меня есть дополнительный вопрос.
Ответ там ссылкиИспользование TRY ... CATCH в Transact-SQLкоторый я вернусь через секунду ...
Мой код (унаследованный, конечно) имеет упрощенную форму:
SET NOCOUNT ON
SET XACT_ABORT ON
CREATE TABLE #tmp
SET @transaction = 'insert_backtest_results'
BEGIN TRANSACTION @transaction
BEGIN TRY
--do some bulk insert stuff into #tmp
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION @transaction
SET @errorMessage = 'bulk insert error importing results for backtest '
+ CAST(@backtest_id as VARCHAR) +
'; check backtestfiles$ directory for error files ' +
' error_number: ' + CAST(ERROR_NUMBER() AS VARCHAR) +
' error_message: ' + CAST(ERROR_MESSAGE() AS VARCHAR(200)) +
' error_severity: ' + CAST(ERROR_SEVERITY() AS VARCHAR) +
' error_state ' + CAST(ERROR_STATE() AS VARCHAR) +
' error_line: ' + CAST(ERROR_LINE() AS VARCHAR)
RAISERROR(@errorMessage, 16, 1)
RETURN -666
END CATCH
BEGIN TRY
EXEC usp_other_stuff_1 @whatever
EXEC usp_other_stuff_2 @whatever
-- a LOT of "normal" logic here... inserts, updates, etc...
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION @transaction
SET @errorMessage = 'error importing results for backtest '
+ CAST(@backtest_id as VARCHAR) +
' error_number: ' + CAST(ERROR_NUMBER() AS VARCHAR) +
' error_message: ' + CAST(ERROR_MESSAGE() AS VARCHAR(200)) +
' error_severity: ' + CAST(ERROR_SEVERITY() AS VARCHAR) +
' error_state ' + CAST(ERROR_STATE() AS VARCHAR) +
' error_line: ' + CAST(ERROR_LINE() AS VARCHAR)
RAISERROR(@errorMessage, 16, 1)
RETURN -777
END CATCH
RETURN 0
Я думаю, что у меня достаточно информации, чтобы просто поиграть с этим и самому разобраться ... к сожалению, воспроизвести ошибку оказалось почти невозможно. Поэтому я надеюсь, что вопрос здесь поможет прояснить мое понимание проблемы и решения.
Эта хранимая процедура периодически выдает такие ошибки:
ошибка импорта результатов для обратного тестирования 9649 error_number: 3930 error_message: текущая транзакция не может быть зафиксирована и не может поддерживать операции записи в файл журнала. Откат транзакции. error_severity: 16 error_state 1 error_line: 217
Итак, очевидно, ошибка исходит от 2-го блока catch
На основании того, что я прочитал вИспользование TRY ... CATCH в Transact-SQLЯ думаю, что происходит, когда возникает исключение, использованиеXACT_ABORT
вызывает "завершение и откат транзакции" ... а затем первая строкаBEGIN CATCH
слепо пытается откатиться снова.
Я не знаю, почему оригинальный разработчик включилXACT_ABORT
, так что я думаю, что лучшее решение (чем его удаление) будет использоватьXACT_STATE()
откатываться только при наличии транзакции (<>0
). Это звучит разумно? Я что-то пропустил?
Кроме того, упоминание о регистрации в сообщении об ошибке заставляет меня задуматься: есть ли другая проблема, возможно, с конфигурацией? Является ли наше использованиеRAISEERROR()
в этом сценарии способствуя проблеме? Это регистрируется в каком-то случае, когда регистрация невозможна, как намекает сообщение об ошибке?