Ошибка транзакции 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() в этом сценарии способствуя проблеме? Это регистрируется в каком-то случае, когда регистрация невозможна, как намекает сообщение об ошибке?

Ответы на вопрос(1)

Ваш ответ на вопрос