Количество транзакций после ошибки EXECUTE - PullRequest
0 голосов
/ 20 апреля 2009

У меня есть хранимая процедура, которая выглядит примерно так:


CREATE PROCEDURE my_procedure 
  @val_1 INT,
  @val_2 INT
AS
SET NOCOUNT ON;
SET XACT_ABORT ON;

BEGIN TRY
  BEGIN TRANSACTION;

  INSERT INTO table_1(col_1, col_2)
  VALUES (@val_1, @val_2);  

  COMMIT TRANSACTION;
END TRY
BEGIN CATCH
  IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION;

  DECLARE
    @ERROR_SEVERITY INT,
    @ERROR_STATE    INT,
    @ERROR_NUMBER   INT,
    @ERROR_LINE     INT,
    @ERROR_MESSAGE  NVARCHAR(4000);

  SELECT
    @ERROR_SEVERITY = ERROR_SEVERITY(),
    @ERROR_STATE    = ERROR_STATE(),
    @ERROR_NUMBER   = ERROR_NUMBER(),
    @ERROR_LINE     = ERROR_LINE(),
    @ERROR_MESSAGE  = ERROR_MESSAGE();

  RAISERROR('Msg %d,
  Line %d,
  :%s',
    @ERROR_SEVERITY,
    @ERROR_STATE,
    @ERROR_NUMBER,
    @ERROR_LINE,
    @ERROR_MESSAGE);
END CATCH

Когда этот код выполняется через базу данных, все работает правильно. При выполнении через ADO.NET я получаю следующее сообщение об ошибке:

"Оператор INSERT конфликтовал с ограничением FOREIGN KEY" FK_table1_table2 ". Конфликт произошел в базе данных" my_database ", таблица" dbo.table_1 ", столбец 'col_1'. Число транзакций после EXECUTE указывает, что отсутствует оператор COMMIT или ROLLBACK TRANSACTION. Предыдущий счетчик = 1, текущий счетчик = 0. "

Это происходит из-за того, что параметр XACT_ABORT принудительно откатывает транзакцию из ADO.NET? Как лучше всего избежать этой ошибки?

Ответы [ 2 ]

2 голосов
/ 26 августа 2009

IF XACT_STATE () = 0 BEGIN COMMIT TRAN TranA END

сгенерирует ошибку. XACT_STATE () = 0 означает, что нет транзакции для фиксации или отката

XACT_STATE () = 1 означает, что транзакция подтверждена

XACT_STATE () = -1 означает, что существует незафиксированная транзакция, которая будет откатана ядром базы данных в конце текущего контекста.

2 голосов
/ 20 апреля 2009

вы можете проверить XACT_STATE () в своем коде, а затем зафиксировать или откатить, проверьте здесь: Используйте XACT_STATE () для проверки обреченных транзакций

в принципе что-то вроде этого взорвется

BEGIN TRANSACTION TranA
    BEGIN TRY
     DECLARE  @cond INT;
     SET @cond =  'A';
    END TRY
    BEGIN CATCH
     PRINT 'a'
    END CATCH;
    COMMIT TRAN TranA

и когда вы проверяете xact_state, вы можете управлять им

BEGIN TRANSACTION TranA
    BEGIN TRY
     DECLARE  @cond INT;
     SET @cond = 'A';
    END TRY
    BEGIN CATCH
     PRINT ERROR_MESSAGE();
    END CATCH;
    IF XACT_STATE() =0
    BEGIN
     COMMIT TRAN TranA
    END
    ELSE
    BEGIN
     ROLLBACK TRAN TranA
    END

Также взгляните на эти две ссылки для чтения Реализация обработки ошибок с помощью хранимых процедур и Обработка ошибок в SQL Server - фон .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...