Обработка ошибок в транзакциях

Завершено

Структурированная обработка исключений использует конструкцию TRY/CATCH для проверки ошибок и обработки ошибок. При использовании обработки исключений с транзакциями важно поместить COMMITROLLBACK ключевые слова в правильное место относительно блоков TRY/CATCH.

Фиксация транзакций

При использовании транзакций с структурированной обработкой исключений поместите COMMIT TRANSACTION внутри блока TRY, как показано в следующем примере кода:

BEGIN TRY
 BEGIN TRANSACTION
 	INSERT INTO dbo.Orders(custid, empid, orderdate)
	VALUES (68,9,'2006-07-12');
	INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
	VALUES (1, 2,15.20,20);
 COMMIT TRANSACTION
END TRY 

Откат транзакции

При использовании со структурированной обработкой исключений поместите ROLLBACK TRANSACTION внутри блока CATCH, как показано в следующем примере кода:

BEGIN TRY
 BEGIN TRANSACTION;
 	INSERT INTO dbo.Orders(custid, empid, orderdate)
	VALUES (68,9,'2006-07-12');
	INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
	VALUES (1, 2,15.20,20);
 COMMIT TRANSACTION;
END TRY
BEGIN CATCH
	SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;
	ROLLBACK TRANSACTION;
END CATCH;

XACT_STATE

Чтобы избежать отката активной транзакции, используйте функцию XACT_STATE . XACT_STATE возвращает следующие значения:

Возвращаемое значение Значение
1 Текущий сеанс имеет активную транзакцию пользователя. Сеанс может выполнять любые действия, включая запись данных и фиксацию транзакции.
0 Нет активной транзакции.
-1 Текущий сеанс имеет активную транзакцию пользователя, но произошла ошибка, которая классифицировала транзакцию как неуправляемую. Сеанс не может зафиксировать или откатить в точку сохранения; он может выполнять только операции чтения и должен выдавать полный ROLLBACK TRANSACTION.

XACT_STATE можно использовать перед командой, чтобы проверить, активна ли транзакция ROLLBACK .

В следующем коде показана функция, используемая XACT_STATE в блоке CATCH. Он отличает состояние -1 (неуправляемый — должен полностью откатить) от состояния 1 (фиксация — может быть зафиксировано):

BEGIN TRY
 BEGIN TRANSACTION;
 	INSERT INTO dbo.SimpleOrders(custid, empid, orderdate) 
	VALUES (68,9,'2006-07-12');
	INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty) 
	VALUES (1, 2,15.20,20);
 COMMIT TRANSACTION;
END TRY
BEGIN CATCH
	SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;

	-- Test for uncommittable transaction (for example, caused by SET XACT_ABORT ON).
	IF XACT_STATE() = -1
	BEGIN
		ROLLBACK TRANSACTION;
	END;

	-- Test for active, committable transaction.
	IF XACT_STATE() = 1
	BEGIN
		COMMIT TRANSACTION;
	END;
	-- If XACT_STATE() = 0, there is no active transaction; no action needed.
END CATCH;