Czy zastanawiałeś się kiedyś, co się stanie, jeżeli wykonując ciąg instrukcji w ramach transakcji doprowadzisz do błędu? Czy transakcja się wykona opuszczając tę pojedynczą nieudaną instrukcję, czy też wycofa wszystkie operacje wykonywane w ramach transakcji? Reguluje to opcja XACT_ABORT.
Przyjrzyjmy się następującemu przykładowi:
1 2 3 4 5 6 7 8 |
CREATE DATABASE Test; GO USE Test; GO CREATE TABLE TestError ( id INT IDENTITY(1,1), nameVARCHAR(100) UNIQUE); GO |
Teraz rozpoczniemy transakcję. W ramach tej transakcji, próbujemy dwa razy wstawic do tabeli rekord o takim samym name. Spowoduje to błąd – naruszenie unikalności tej kolumny!
1 2 3 4 5 6 |
BEGIN TRANSACTION INSERT INTO TestError VALUES ('jeden'); INSERT INTO TestError VALUES ('jeden'); INSERT INTO TestError VALUES ('dwa'); COMMIT TRANSACTION GO |
1 |
<a href="http://www.mobilo24.eu/wp-content/uploads/2011/03/xact_abort1error.png"><img class="alignnone size-full wp-image-412" title="xact_abort1error" src="http://www.mobilo24.eu/wp-content/uploads/2011/03/xact_abort1error.png" alt="" width="876" height="100" /></a> |
Co znalazło się w tabeli TestError?
1 2 |
SELECT TRANSACTION * FROM TestError; GO |
Cóż – mamy 2 rekordy. Czyli pierwszy i ostatni INSERT się udał.
Gdybyś chciał to zmienić możesz użyć opcji
1 |
SET XACT_ABORT ON |
Powoduje ona, że kiedy podczas transakcji zostanie napotkany błąd, to transakcja zostanie wycofana w całości.
1 2 3 4 |
CREATE TABLE TestError2 ( id INT IDENTITY(1,1), nameVARCHAR(100) UNIQUE); GO |
1 |
SET XACT_ABORT ON |
1 2 3 4 5 6 |
BEGIN TRANSACTION INSERT INTO TestError2 VALUES ('jeden'); INSERT INTO TestError2 VALUES ('jeden'); INSERT INTO TestError2 VALUES ('dwa'); COMMIT TRANSACTION GO |
1 |
<a href="http://www.mobilo24.eu/wp-content/uploads/2011/03/xact_abort2error.png"><img class="alignnone size-full wp-image-414" title="xact_abort2error" src="http://www.mobilo24.eu/wp-content/uploads/2011/03/xact_abort2error.png" alt="" width="882" height="54" /></a> |
Jeżeli teraz sprawdzimy zawartość tabeli:
1 2 |
SELECT TRANSACTION * FROM TestError2; GO |
to okaże się, że jest ona pusta! Żaden rekord się nie zapisał, bo drugi INSERT wygenerował błąd, który wycofał transakcję.
Domyślnie opcja XACT_ABORT jest wyłączona.
Opcją XACT_ABORT możesz regulować „czułość” transakcji na błedy. Chcesz by transakcja była czuła i przy pierwszym błedzie spanikowała i wycofała się, przestaw opcję na ON. Chcesz by transakcja zapisała co może pomijając błedne dane – przestaw opcję na OFF.
Więcej o transakcjach na mobilo (mobilo24):
Dokładniej o tej opcji:
http://msdn.microsoft.com/en-us/library/ms188792.aspx