Какой тип ошибки приводит к тому, что XACT_STATE равен 1 в MS SQL Server? - PullRequest
0 голосов
/ 29 мая 2018

На основе документа Microsoft о TRY ... CATCH, когда значение XACT_STATE равно -1, транзакции не выполняются ( TRY ... CATCH (Transact-SQL) ):

Uncommittable транзакции и XACT_STATE

Если из-за ошибки, генерируемой в блоке TRY, состояние текущей транзакции становится недействительным, транзакция классифицируется как незафиксированная транзакция. Ошибка, которая обычно завершает транзакцию вне блока TRY, приводит к тому, что транзакция переходит в состояние uncommittable, когда ошибка происходит внутри блока TRY. Неконмитируемая транзакция может выполнять только операции чтения или транзакцию ROLLBACK.Транзакция не может выполнить какие-либо операторы Transact-SQL, которые бы генерировали операцию записи или COMMIT TRANSACTION.Функция XACT_STATE возвращает значение -1, если транзакция была классифицирована как незафиксированная транзакция.Когда пакет завершается, компонент Database Engine откатывает любые активные незафиксированные транзакции.Если сообщение об ошибке не было отправлено, когда транзакция перешла в состояние uncommittable, когда пакет завершается, клиентское приложение отправит сообщение об ошибке.Это означает, что незафиксированная транзакция была обнаружена и откатана.

Если я правильно понимаю, каждая ошибка, которая останавливает непрерывность блока TRY и входит в блок CATCH, приводит к тому, что XACT_STATE равен -1 (когда XACT_ABORTвключен), но в примере C упомянутого документа проверяет, если равен 1:

.,,END TRY BEGIN CATCH - Выполнить процедуру поиска ошибок.
EXECUTE usp_GetErrorInfo;

-- Test XACT_STATE:  
    -- If 1, the transaction is committable.  
    -- If -1, the transaction is uncommittable and should   
    --     be rolled back.  
    -- XACT_STATE = 0 means that there is no transaction and  
    --     a commit or rollback operation would generate an error.  

-- Test whether the transaction is uncommittable.  
IF (XACT_STATE()) = -1  
BEGIN  
    PRINT  
        N'The transaction is in an uncommittable state.' +  
        'Rolling back transaction.'  
    ROLLBACK TRANSACTION;  
END;  

-- Test whether the transaction is committable.  
IF (XACT_STATE()) = 1  
BEGIN  
    PRINT  
        N'The transaction is committable.' +  
        'Committing transaction.'  
    COMMIT TRANSACTION;     

END; END CATCH; GO

Мой вопрос здесь:

Это неправильный пример?Если нет, то какие ошибки могут привести к тому, что XACT_STATE будет 1 (committable) в блоке CATCH?

1 Ответ

0 голосов
/ 29 мая 2018

SQL Server может допускать некоторые ошибки внутри транзакции без необходимости помечать ее как нефиксированную.Например, SELECT 1/0 приведет к ошибке, но не приведет к переводу транзакции в нефиксированное состояние.(Цитируется из https://docs.microsoft.com/en-us/azure/sql-data-warehouse/sql-data-warehouse-develop-transactions.)

Фактически, если не включен XACT_ABORT, практически любая нефатальная ошибка приведет к XACT_STATE, равному 1 (нарушение pk, преобразование типов данных, нарушение ограничений и т. Д.).от https://www.sqlservercentral.com/Forums/Topic1109613-1550-1.aspx).

...