2012-04-14 7 views
151

Mam 2 polecenia i trzeba je poprawnie wykonać lub żadna z nich nie zostanie wykonana. Więc myślę, że potrzebuję Transakcji, ale nie wiem, jak jej używać poprawnie.Prawidłowe korzystanie z transakcji w SQL Server 2008

Na czym polega problem z następującym skryptem?

BEGIN TRANSACTION [Tran1] 

INSERT INTO [Test].[dbo].[T1] 
    ([Title], [AVG]) 
VALUES ('Tidd130', 130), ('Tidd230', 230) 

UPDATE [Test].[dbo].[T1] 
    SET [Title] = N'az2' ,[AVG] = 1 
    WHERE [dbo].[T1].[Title] = N'az' 

COMMIT TRANSACTION [Tran1] 
GO 

Komenda insert stracony ale komenda update ma problem. Jak mogę to zaimplementować, aby wycofać oba polecenia, jeśli któryś z nich ma błąd w wykonaniu?

Odpowiedz

350

Dodaj blok try/catch, jeśli transakcja się powiedzie będzie to zatwierdzić zmiany, jeśli transakcja nie transakcja zostanie wycofana:

BEGIN TRANSACTION [Tran1] 

BEGIN TRY 

INSERT INTO [Test].[dbo].[T1] 
    ([Title], [AVG]) 
VALUES ('Tidd130', 130), ('Tidd230', 230) 

UPDATE [Test].[dbo].[T1] 
    SET [Title] = N'az2' ,[AVG] = 1 
WHERE [dbo].[T1].[Title] = N'az' 


COMMIT TRANSACTION [Tran1] 

END TRY 
BEGIN CATCH 
    ROLLBACK TRANSACTION [Tran1] 
END CATCH 

GO 
+13

Jest to bardziej właściwe odpowiedzi. –

+9

Dobra odpowiedź. Jak napisano, spowoduje to zablokowanie komunikatu o błędzie. Dodaj "PRINT ERROR_MESSAGE()" po wycofaniu, aby go wyświetlić. – atheaos

+1

Czy nie należy "BEGIN TRANSACTION [Tran1]" umieścić w środku "TRY"? W każdym razie - bardzo prosty i elegancki kawałek kodu. –

95

Na początku procedury składowanej należy umieścić SET XACT_ABORT ON pouczać Serwer Sql do automatycznego wycofania transakcji w przypadku błędu. Jeśli pominięto lub ustawiono na WYŁĄCZENIE, po każdej instrukcji trzeba przetestować @@ERROR lub użyć bloku TRY ... CATCH rollback.

+4

Jak to może być zaakceptowana odpowiedź? –

+4

Ponieważ jest to [poprawna odpowiedź] (https://msdn.microsoft.com/en-us/library/ms188792.aspx): "Gdy SET XACT_ABORT jest WYŁĄCZONA, w niektórych przypadkach jest to tylko instrukcja Transact-SQL, która podniesiony błąd jest wycofywany, a transakcja kontynuowana jest przetwarzanie.W zależności od wagi błędu cała transakcja może zostać wycofana, nawet jeśli SET XACT_ABORT jest WYŁĄCZONA, OFF to ustawienie domyślne. " Pierwotne pytanie brzmi: dlaczego INSERT ma miejsce, ale AKTUALIZACJA jest wycofana. Nawet przy użyciu TRY-CATCH, twój INSERT zostanie uruchomiony jako pierwszy i zostanie zatwierdzony. TRY-CATCH może jednak nadal być wykorzystywany do elastyczności. – 4AM

+1

Innymi słowy, twoja transakcja nie jest atomowa, chyba że najpierw ustawisz XACT_ABORT ON. – 4AM

22

Łatwy dojazd:

CREATE TABLE T 
(
    C [nvarchar](100) NOT NULL UNIQUE, 
); 

SET XACT_ABORT ON -- Turns on rollback if T-SQL statement raises a run-time error. 
SELECT * FROM T; -- Check before. 
BEGIN TRAN 
    INSERT INTO T VALUES ('A'); 
    INSERT INTO T VALUES ('B'); 
    INSERT INTO T VALUES ('B'); 
    INSERT INTO T VALUES ('C'); 
COMMIT TRAN 
SELECT * FROM T; -- Check after. 
DELETE T; 
Powiązane problemy