Znaczenie atrybutu XACT_ABORT

Aby wyjaśnić znaczenie atrybutu stwórzmy najpierw tabelę składają się wyłącznie z jednej kolumny – klucza głównego. Ponadto nie ustawiajmy IDENTITY dla tej kolumny. Następnie spróbujmy wykonać 2 poniższe  insert’y:

begin transaction
insert into TestSet (ID) values(1);
insert into TestSet (ID) values(1);
commit transaction;

Przy drugim insercie wyskoczy błąd. To jest oczywiste ponieważ klucz główny musi być unikalny. Jeśli jednak odpalimy select’a przekonamy się, że wartości z pierwszego insert’a zostały wstawione (1). Dzieje się tak ponieważ domyślnie transakcja nie jest anulowana w przypadku wystąpienia błędu. Aby temu zaradzić należy ustawić właśnie zmienną XACT_ABORT na true:

SET XACT_ABORT on
go
begin transaction
insert into TestSet (ID) values(1);
insert into TestSet (ID) values(1);
commit transaction;

XACT_ABORT powoduje, że w przypadku wystąpienia błędu cała transakcja jest anulowana (rollback). Do bazy nie zostanie dodany żaden wpis – nawet pierwszy insert, który nie powoduje błędu.

6 thoughts on “Znaczenie atrybutu XACT_ABORT”

  1. I to jest właśnie duży minus MS SQL! Gdy jakaś zapytanie w ciąg odpalanych instrukcji spowoduje błąd to instrukcje wykonują się do końca. Powinno zostać przerwane oraz cofnięte. Np. gdy mamy procedure, a w niej jakiś ciąg instrukcji. To gdy w środku jedno z zapytań spowoduje błąd, dalsze instrukcje zostaną wykonane, a całość prócz błędnego zapytania zostanie zatwierdzona – masakra;)

  2. –Gwoli wyklarowania tematu:
    –zalecana metoda obslugi transakcji jest
    begin transaction
    BEGIN TRY
    insert into TestSet (ID) values(1);
    insert into TestSet (ID) values(2);

    commit transaction;
    print ‘all ok!!!!’
    END TRY
    BEGIN CATCH
    print ‘exception!!!!’
    rollback transaction;
    END CATCH
    –wtedy wszystko dziala pieknie bez XACT_ABORT

  3. –Gwoli wyklarowania tematu:
    –zalecana metoda obslugi transakcji jest:
    begin transaction
    BEGIN TRY
    insert into TestSet (ID) values(1);
    insert into TestSet (ID) values(2);

    commit transaction;
    print ‘all ok!!!!’
    END TRY
    BEGIN CATCH
    print ‘exception!!!!’
    rollback transaction;
    END CATCH
    –wtedy wszystko dziala pieknie bez XACT_ABORT

  4. @Koto: oczywiście masz racje ale celem post’a było przedstawienie atrybutu a nie obsługa transakcji.

    Pozdrawiam,
    Piotr Zielinski

  5. Poza powyższym – nie wszystkie błędy są wyłapywane przez begin catch end catch.

Leave a Reply

Your email address will not be published.